我有一个USB串行端口模块,我想在我的C应用程序中使用它。问题是 open 系统调用未返回!
int serialDevice = open(“ / dev / ttyUSB0”,O_RDWR | O_NOCTTY); //不返回
我将用户添加到了拨出组,并且可以使用终端中的minicom来访问端口而无需root访问。因此,这不是许可问题。即使是这样,它也应该立即返回并给出权限错误。但是open函数根本不会返回。
我该怎么办?你有什么主意吗?
谢谢
答案 0 :(得分:2)
我相信如果设备繁忙等情况,可能会发生这种情况。
您需要添加标志 O_NONBLOCK :
O_NONBLOCK 使用O_RDONLY或O_WRONLY设置打开FIFO时: * 如果设置了O_NONBLOCK,则只读的open()将立即返回。如果没有,open()仅用于写操作将返回错误 进程当前已打开文件以供读取。 * 如果清除了O_NONBLOCK,则只读的open()将阻塞调用线程,直到线程打开要写入的文件为止。一个open() 仅用于写将阻塞调用线程直到线程打开 要读取的文件。
打开支持的特殊块或字符特殊文件时 非阻塞打开:
设备的* If O_NONBLOCK is set, the open() function shall return without blocking for the device to be ready or available. Subsequent behavior
是特定于设备的。 * 如果清除了O_NONBLOCK,则open()函数将阻塞调用线程,直到设备准备就绪或可用之前 返回。
否则,未指定O_NONBLOCK的行为。
答案 1 :(得分:2)
int serialDevice = open(“ / dev / ttyUSB0”,O_RDWR | O_NOCTTY);
除了@darune的答案和O_NONBLOCK
,您也可以考虑使用O_SYNC
。另请参见How to open, read, and write from serial port in C?
您可能还考虑将文件描述符设为互斥的,以便其他程序(如调制解调器管理器)不会打开设备和muck with your state。由于O_RDWR
,排他性很好。另请参阅内核新手邮件列表上的How to make /dev/ttyACM0 (and friends) exclusive?。
要使文件描述符互斥,您需要使用ioctl
和TIOCEXCL
。 O_EXCL
不能按预期方式工作,因为它不适合字符设备使用(内核人士说-ENOPATCH
)。
int term_config(int fd, int speed)
{
struct termios tty;
memset(&tty, 0, sizeof(tty));
if (tcgetattr(fd, &tty) != 0) {
log_error("term_config: tcgetattr: %s\n", strerror(errno));
return -1;
}
cfmakeraw(&tty);
tty.c_cflag |= CLOCAL; /* ignore status lines */
tty.c_cflag |= CRTSCTS; /* hardware flow control */
cfsetospeed(&tty,(speed_t)speed);
cfsetispeed(&tty,(speed_t)speed);
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
log_error("term_config: tcsetattr: %s\n", strerror(errno));
return -1;
}
if (ioctl(fd, TIOCEXCL, NULL) != 0) {
log_error("term_config: ioctl_tty: %s\n", strerror(errno));
return -1;
}
return 0;
}
您会给term_config
打电话,例如:
int serialDevice = open("/dev/ttyUSB0", ...);
if (serialDevice == -1) { /* error */ }
int result = term_config(serialDevice, B115200);
if (result != 0) { /* error */ }