代码之家  ›  专栏  ›  技术社区  ›  anorm

从串行端口读取失败

  •  6
  • anorm  · 技术社区  · 16 年前

    我有以下C程序:

    #include <fcntl.h>
    #include <termios.h>
    #include <stdio.h>
    
    int main()
    {
        int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
        if(fd < 0)
        {
            perror("Could not open device");
        }
        printf("Device opened\n");
    
        struct termios options;
        tcgetattr(fd, &options);
        cfmakeraw(&options);
        cfsetispeed(&options, B19200);
        cfsetospeed(&options, B19200);
        tcsetattr(fd, TCSANOW, &options);
    
        char txpacket[] = {0x23, 0x06, 0x00, 0x00, 0xdd, 0xf9};
        ssize_t written = write(fd, txpacket, sizeof(txpacket));
        printf("Written %d bytes\n", written);
    
        printf("Starting to wait for target to respond\n");
        while(1)
        {
            fd_set readset;
            FD_ZERO(&readset);
            FD_SET(fd, &readset);
            int nCount = select(fd + 1, &readset, NULL, NULL, NULL);
            if(nCount > 0)
            {
                if(FD_ISSET(fd, &readset))
                {
                    int i;
                    char buffer[128];
                    ssize_t bytesread = read(fd, buffer, sizeof(buffer));
                    printf("Received %d bytes\n", bytesread);
                    for(i = 0; i < bytesread; i++)
                    {
                        printf("  %02x", buffer[i]);
                    }
                }
            }
        }
    }
    

    这个程序打开串行设备/dev/ttys0,向其写入一系列数据,并开始监听响应。我得到以下输出:

    Device opened
    Written 6 bytes
    Starting to wait for target to respond
    Received 0 bytes
    Received 0 bytes
    Received 0 bytes
    Received 0 bytes
    Received 0 bytes
    Received 0 bytes
    ...
    

    应用程序消耗100%的CPU。我无法接收任何数据,即使目标硬件确实传输了它。

    怎么了?

    2 回复  |  直到 7 年前
        1
  •  7
  •   caf    16 年前

    read() 返回0表示文件结束条件。你应该检查一下,如果它发生了,就跳出循环。

    至于是什么导致了串行端口上的-end-of-file表明它检测到了挂断,这意味着DCD线路已经断开。

    你可以设置 CLOCAL 标记 options.c_cflag 要忽略调制解调器控制线,如果您的设备没有正确设置它们。

        2
  •  1
  •   shodanex    16 年前

    您应该尝试不使用O_nonblock标志。在原始模式下,如果 c_cc[VMIN] c_cc[VTIME] 为0,串行端口的行为如下(根据man cfmakeraw):

    如果数据可用,则read返回 立即,以较小的 可用字节数,或 请求的字节数。如果没有数据 可用,read返回0

    所以你应该尝试的是:

    options->c_cc[VMIN]=1;