Can';t在C中设置Linux中的串行端口配置
我已经编写了一些Linux程序来与我的设备通信。我有“相同”的Windows程序(“相同”是因为它的逻辑相同)。 我使用的是9600 bps的8N2数据帧格式,既没有软件(XOn/XOff)也没有硬件(RTS/CTS)流量控制。我不使用RS-232 9针D-sub的DTR、DCD、RI、DSR引脚。我只使用RX和TX引脚与设备通信。 在Linux中,我有这部分代码:Can';t在C中设置Linux中的串行端口配置,c,linux,serial-port,C,Linux,Serial Port,我已经编写了一些Linux程序来与我的设备通信。我有“相同”的Windows程序(“相同”是因为它的逻辑相同)。 我使用的是9600 bps的8N2数据帧格式,既没有软件(XOn/XOff)也没有硬件(RTS/CTS)流量控制。我不使用RS-232 9针D-sub的DTR、DCD、RI、DSR引脚。我只使用RX和TX引脚与设备通信。 在Linux中,我有这部分代码: struct termios PortOpts, result; int fd; /* File descriptor for
struct termios PortOpts, result;
int fd; /* File descriptor for the port */
/* Configure Port */
tcgetattr(fd, &PortOpts);
// BaudRate - 9600
cfsetispeed(&PortOpts, B9600);
cfsetospeed(&PortOpts, B9600);
// enable reciever and set local mode, frame format - 8N2, no H/W flow control
PortOpts.c_cflag &= (~(CLOCAL | CREAD | CSIZE | CSTOPB));
PortOpts.c_cflag |= ((CLOCAL | CREAD | CS8 | CSTOPB) & (~PARENB));
PortOpts.c_cflag &= (~CRTSCTS);
// PortOpts.c_cflag &= ~PARENB
// PortOpts.c_cflag |= CSTOPB
// PortOpts.c_cflag &= ~CSIZE;
// PortOpts.c_cflag |= CS8;
// no parity check, no software flow control on input
PortOpts.c_iflag |= IGNPAR;
PortOpts.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY | INPCK);
// raw data input mode
PortOpts.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
// raw data output
PortOpts.c_oflag &= ~OPOST;
// setting timeouts
PortOpts.c_cc[VMIN] = 1; // minimum number of chars to read in noncanonical (raw mode)
PortOpts.c_cc[VTIME] = 5; // time in deciseconds to wait for data in noncanonical mode (raw mode)
if (tcsetattr(fd, TCSANOW, &PortOpts) == 0) {
tcgetattr(fd, &result);
if ( (result.c_cflag != PortOpts.c_cflag) ||
(result.c_oflag != PortOpts.c_oflag) ||
(result.c_iflag != PortOpts.c_iflag) ||
(result.c_cc[VMIN] != PortOpts.c_cc[VMIN]) ||
(result.c_cc[VTIME] != PortOpts.c_cc[VTIME]) ) {
perror("While configuring port1");
close(fd);
return 1;
}
} else {
perror("While configuring port2");
close(fd);
return 1;
};
文件描述符“fd”用于“/dev/ttyS0”设备。
我在配置端口2时收到消息::输入/输出错误
我有一台笔记本电脑,但除了USB外,我没有任何串行端口。这是原因吗?
我以root用户身份运行程序
对不起,我的英语不好。你能在程序上运行strace吗;这将给出IO错误发生的具体位置
需要记住的一点是,errno不会被重置,因此实际错误可能来自perror之前的任何系统调用。明显的问题是“fd的值是多少?”也就是说,您是否检查了
open()
的返回值?为什么不检查tcgetattr()
的返回值?有关使用cfmakeraw()
的更简单的代码示例,请参阅@sawdust fd is 3。设备文件打开正常。我已经阅读了有关cfmakeraw()
的手册,但它将生成8N1帧格式。当然,当一次传输不超过1字节时,有多少停止位并不重要,但这是最基本的。你是对的。我在获取串口参数时遇到了相同的错误。这是因为没有物理设备?如果您使用的是USB-RS232适配器,请发出shell命令ls/dev/ttyUSB*
。将该设备名称用于open()
,而不是/dev/ttyS0
。现代UART或USART很少需要两个停止位。我(和许多其他人)对115200波特使用1个停止位,字符间间隙为零或最小,没有任何问题。超过1个停止位的典型原因是波特率发生器不准确。@sawdust我没有任何适配器。我需要检查我的程序是否运行正常(至少是预传输块)。谢谢你关于停止位的提示。我将尝试使用1个停止位。我已经编写了几十年的驱动程序,不知道如何在不存在的硬件上使用实际的系统调用。open()
应该失败;这是一个太宽容的设备驱动程序。如果没有设备,则必须绕过所有I/O和设备控制的系统调用,并用模拟功能替换。