【问题标题】:Serial Programming - Termios. Getting stuck when reading 0x00 byte from device串行编程 - Termios。从设备读取 0x00 字节时卡住
【发布时间】:2019-03-12 13:09:56
【问题描述】:

我正在使用termios API 读取/写入串行接口中配置的设备。我使用的代码如下:

// Open serial interface
const char *device = "/dev/ttyS0";
int fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1)
  printf( "failed to open port\n" );

fcntl(fd, F_SETFL, 0);

// Get current configuration of serial interface
struct termios config;
tcgetattr(fd, &config);

// Set configuration of device
...
...
//

// Apply configuration to descriptor
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &config);

// Send order to device
unsigned char order[2];
int res;
unsigned char m = 0x00;
unsigned char s = 0x00;

order[0] = 0xc1; // Byte 193
order[1] = m;

res = write(fd, &order[0], 2);
if (res != 2)
  return -1;

res = read(fd, &s, 1);
if ((res != 1) || (res == -1))
  return -1;

串口正确打开,设备也正确配置。如果我在 gdb 中打印配置 (config),我会得到以下信息:

{c_iflag = 8240, c_oflag = 0, c_cflag = 3251, c_lflag = 0, c_cc = "\003\034\177\025\004\000\000\000\021\023\032\000\000\000\000\026\001\000\000\000\033[\000\000\000 \000\000\000DCAB@P\000\000HY\000", 保留 = {0, 0, 1552337580}, c_ispeed = 9600, c_ospeed = 9600}

然后我可以使用 write 功能向设备发送订单,但我不能使用 read 功能。运行res = read(fd, &s, 1); 行后代码卡住了,我没有得到任何响应(见下文)。有什么提示吗?

编辑:

// Set configuration of device 块如下:

cfsetispeed(&config, B9600);
cfsetospeed(&config, B9600);

config.c_cflag &= ~CSIZE;
config.c_cflag |= CS8;    

config.c_cflag &= ~CSTOPB;
config.c_cflag |= 0;

config.c_cflag &= ~PARENB;
config.c_cflag &= ~PARODD;
config.c_cflag |= (0 | 0);

config.c_cflag |= (CLOCAL | CREAD);
config.c_iflag |= (INPCK | ISTRIP);

config.c_oflag = 0;
config.c_lflag = 0;

config.c_cc[VMIN]=1;
config.c_cc[VTIME]=0;

【问题讨论】:

  • 确定有东西可以从串口读取吗?如果使描述符非阻塞,read 是否返回 -1errno 设置为 EAGAINEWOULDBLOCK
  • “0x00字节”是从哪里来的,它的意义是什么?例如,如果它应该是一个字符串终止符,那么我可以想象 sender-side 缺陷的几种变体,它们会在终止符之前的最后一个字节结束传输。
  • @Someprogrammerdude 设备已连接到串口。我不知道read 是否返回-1,因为代码卡住了。 @John Bollinger 0x00 字节应该是设备处于非活动状态的默认值。
  • 你的“代码卡住”的原因是因为没有什么可读的。由于描述符是 blocking 这意味着 read 将永远阻塞(即不会返回并且似乎被卡住),直到实际上有任何东西要读取。如果您为描述符fd 设置O_NONBLOCK 标志,那么read 调用将返回-1,并将errno 设置为我之前评论中提到的错误之一。
  • @Someprogrammerdude 那么解决方案是什么?我刚刚尝试删除O_NONBLOCK,但问题仍然存在

标签: c unix serial-port posix termios


【解决方案1】:

虽然在打开的时候添加了O_NONBLOCK,但是下面调用了fcntl(fd, F_SETFL, 0),相当于阻塞模式。

fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
fcntl(fd, F_SETFL, 0);   // The O_NONBLOCK flag is overwritten

如果串口没有数据,就会被阻塞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多