Can';t在C中设置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

我已经编写了一些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 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和设备控制的系统调用,并用模拟功能替换。