gpt4 book ai didi

c - epoll 读取错误的字节

转载 作者:太空宇宙 更新时间:2023-11-04 13:01:24 25 4
gpt4 key购买 nike

我是 linux 系统编程的新手,所以请多多关照。我必须通过 RS-422 在 8N1 模式下以波特率 921600 从串行端口 (/dev/ttyX) 读取数据,没有奇偶校验。stty 输出信号表示支持此波特率。所以我决定调用 epoll。问题是 epoll 返回了错误的字节。由于我指定了消息格式,因此我尝试通过手动验证传入数据来进行调试。所以我画了这个: enter image description here

所有消息的尾部都有 2 个字节的 crc。11 b5 表示消息开始。消息的长度应为 36 个字节。72 b5 是另一个消息开始标记。 112 字节长度。73 b5 也是消息标记。 36 个字节。请找到蓝色下划线:这是一条好消息。小红+大红不好。它是 37 字节 len。我有一个额外的字节和 crc 不匹配。下一个好的(绿色)。下一个坏的。它是 114 字节而不是 112 字节,当然 crc 不匹配。

这是我的代码:

... All necessary includes

#define SERIAL_BAUD 921600
#define MAXEVENTS 1024

int openSerial()
{
struct termios options;
int fd;

if ((fd = open("/dev/ttyUSB0", O_RDWR)) == -1)
{
return -1;
}

if (tcgetattr(fd, &options) < 0)
{
printf("Unable to get options with tcgetattr\n");
return -1;
}

if (cfsetispeed(&options, SERIAL_BAUD) < 0)
{
printf("Unable to set input speed with cfsetispeed\n");
return -1;
}

if (cfsetospeed(&options, SERIAL_BAUD) < 0)
{
printf("Unable to set output speed with cfsetispeed\n");
return -1;
}

cfmakeraw(&options);

//options.c_cflag |= SERIAL_BAUD; // Set Baudrate first time
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CRTSCTS;

options.c_cflag &= ~ECHO; // Disable echoing of input characters
options.c_cflag &= ~ECHOE;

// set to 8N1
options.c_cflag &= ~PARENB; // no parity
options.c_cflag &= ~CSTOPB; // 1 stop bit
options.c_cflag &= ~CSIZE; // Mask the character size bits
options.c_cflag |= CS8; // 8 data bits

options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);

options.c_oflag = 0;

options.c_cc[VTIME] = 2; // inter-character timer
options.c_cc[VMIN] = 1; // blocking read until

if (tcflush(fd, TCIFLUSH) < 0)
{
printf("Unable to flush fd with tcflush\n");
return -1;
}

if (tcsetattr(fd, TCSANOW, &options) != 0)
{
printf("Unable to set options with tcsetattr\n");
return -1;
}

return fd;
}

int main(void)
{
int fd;
int efd;
struct epoll_event event;
struct epoll_event* events;
int length;
unsigned char buff[512];

if ((fd = openSerial()) < 0)
{
printf("Exiting because of openSerial failure\n");
return 1;
}

efd = epoll_create1(0);

event.data.fd = fd;
event.events = EPOLLIN;

if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event) < 0)
{
printf("Epoll_ctl error occured\n");
return 1;
}

events = (epoll_event*) calloc(MAXEVENTS, sizeof(event));

for(;;)
{
int n = epoll_wait(efd, events, MAXEVENTS, 5000);

if (n < 0)
{
// No ready descriptors, so wait a bit longer
continue;
}

if(events[0].events & EPOLLIN)
{
length = read(events[0].data.fd, buff, sizeof(buff) / 2);

if(length > 0)
{
printf("\n------MESSAGE START-------\n");
for (int i = 0 ; i < length ; ++i)
{
if (i && i % 16 == 0)
{
printf("\n");
}
printf("%02x ", buff[i]);
}

printf("\n------MESSAGE FINISH-------\n");
}
}
else if(events[0].events & EPOLLOUT)
{
// TODO Write here to serial
}
else if(events[0].events & EPOLLHUP || events[0].events & EPOLLERR)
{
printf("Error occured on serial port\n");
}
else
{
printf("No data whthin 5 seconds.\n");
}
}

free(events);
close(fd);

return 0;
}

最佳答案

您的问题是 read() 返回的字节不符合您的预期。我认为没有理由相信 epoll 与此有任何关系。

我也没有理由认为 read() 传送的字节与系统从设备 /dev/ttyUSB0 接收到的字节不同。如果这些与您的预期不同,那么我倾向于认为设备出现故障或您的预期不正确(或至少不完整)。

关于c - epoll 读取错误的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33805757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com