一、测试环境
硬件:nuc980 开发版
系统:Linux 4.4
二、open 函数描述
函数 open 的介绍
头文件
#include <fcntl.h>
原型
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
标志说明
O_CREAT 时,mode 参数如下:
If pathname does not exist, create it as a regular file.
The owner (user ID) of the new file is set to the effective user ID of the process.
The group ownership (group ID) of the new file is set either to the effective group ID of the process (System V semantics) or to the group ID of the parent directory (BSD semantics).
On Linux, the behavior depends on whether the set-group-ID mode bit is set on the parent directory: if that bit is set, then BSD semantics apply; otherwise, System V semantics apply.
For some filesystems, the behavior also depends on the bsdgroups and sysvgroups mount options described in mount(8).
The mode argument specifies the file mode bits to be applied when a new file is created. If neither O_CREAT nor O_TMPFILE is specified in flags, then mode is ignored (and can thus be
specified as 0, or simply omitted). The mode argument must be supplied if O_CREAT or O_TMPFILE is specified in flags; if it is not supplied, some arbitrary bytes from the stack will be
applied as the file mode.
The effective mode is modified by the process's umask in the usual way: in the absence of a default ACL, the mode of the created file is (mode & ~umask).
Note that mode applies only to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.
The following symbolic constants are provided for mode:
S_IRWXU 00700 user (file owner) has read, write, and execute permission
S_IRUSR 00400 user has read permission
S_IWUSR 00200 user has write permission
S_IXUSR 00100 user has execute permission
S_IRWXG 00070 group has read, write, and execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 others have read, write, and execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
According to POSIX, the effect when other bits are set in mode is unspecified. On Linux, the following bits are also honored in mode:
S_ISUID 0004000 set-user-ID bit
S_ISGID 0002000 set-group-ID bit (see inode(7)).
S_ISVTX 0001000 sticky bit (see inode(7)).
三、问题描述和解决办法
open 原 标志是
O_RDWR | O_NOCTTY
当程序意外关闭并且重新启动后,发现串口不能使用,发送数据失败。
解决办法:
将 标志改为
O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL
或者
O_RDWR | O_NOCTTY | O_NDELAY
测试程序意外关闭后,重新启动程序,串口可正常发送数据。
O_NDELAY 标志在 Linux 的 open 函数中与 O_NONBLOCK 标志是等价的。这两个标志都用于以非阻塞方式打开文件或设备。当使用这些标志时,如果操作不能立即完成(例如,读操作没有数据可读),则调用会立即返回,而不是等待操作完成。
具体来说,当以非阻塞方式打开文件或设备时,如果尝试进行读操作但当前没有数据可读,那么读调用会立即返回一个错误(通常是 -EAGAIN 或 -EWOULDBLOCK),而不是阻塞等待数据到达。同样,如果尝试进行写操作但当前无法立即写入数据(例如,因为缓冲区已满),写调用也会立即返回错误。
这种非阻塞模式特别适用于需要同时处理多个输入/输出操作的应用程序,因为它允许程序在等待操作完成时继续执行其他任务,从而提高了程序的响应性和效率。
在编写使用 open 函数和 O_NDELAY(或 O_NONBLOCK)标志的程序时,开发者需要准备好处理可能的即时错误返回,并根据应用程序的逻辑采取适当的行动(例如,稍后重试操作、记录错误或通知用户)。
请注意,虽然 O_NDELAY 和 O_NONBLOCK 在功能上等价,但不同的系统和库可能会倾向于使用其中一个名称。在编写可移植的代码时,最好查阅目标平台的文档以了解具体使用哪个标志。然而,在大多数现代 Linux 系统上,这两个标志是可以互换使用的。