C-LINUX中串口读取的不一致性
我在使用Linux和C读取串行端口时遇到了不一致的问题 我用于配置串行端口的代码如下:C-LINUX中串口读取的不一致性,c,linux,serial-port,termios,C,Linux,Serial Port,Termios,我在使用Linux和C读取串行端口时遇到了不一致的问题 我用于配置串行端口的代码如下: serial = open("/dev/ttymxc1", O_RDWR | O_NOCTTY | O_SYNC); //Open in non blocking read/write mode if (serial == -1) { //ERROR - CAN'T OPEN SERIAL PORT printf("Error - Unable to
serial = open("/dev/ttymxc1", O_RDWR | O_NOCTTY | O_SYNC); //Open in non blocking read/write mode
if (serial == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (serial, &tty) != 0)
{
printf("error from tcgetattr");
return -1;
}
cfsetospeed (&tty, B115200);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
//tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= 0;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (serial, TCSANOW, &tty) != 0)
{
printf("error from tcsetattr");
return -1;
}
然后,我使用以下代码轮询UART(来自配置串行端口的同一线程):
while(1)
{
if (serial != -1)
{
//memset(rx, 0, sizeof(rx));
int rx_length = read(serial, &rx, MAX_TXRX_BUF); //Filestream, buffer to store in, number of bytes to read (max)
if(rx_length > 0){
//Bytes received
//rx[rx_length] = '\0';
printf("1) %i bytes read : %s\n", rx_length, rx);
//forward_data(rx, rx_length);
printf("2) %i bytes read : %s\n", rx_length, rx);
//tcflush(serial, TCIOFLUSH);
}
// else: NO DATA
}
else{
fprintf(stderr, "TEST: %s SERIAL FAIL\n", __func__);
releaseUart();
}
}
问题是这张照片:
printf("1) %i bytes read : %s\n", rx_length, rx);
始终工作并打印从串行存储器读取的正确数据。
第二次打印时:
printf("2) %i bytes read : %s\n", rx_length, rx);
它位于第一个字符的正下方,有时有效,而其他项目它只打印一个未知字符
下面我向您展示输出,但在其工作和不工作的情况下:
正确:
1) 2 bytes read : gv
2) 2 bytes read gv
错:
1) 2 bytes read : gv
2) 2 bytes read: �
为什么即使两张打印的图片一张比另一张低,有时我在打印同一个缓冲区时也会出现这种不一致的情况
非常感谢你的帮助
致以最良好的祝愿,
Marco我无法解释为什么输出在第一个
printf
和第二个之间变化。但是,read
不会NUL终止其缓冲区,这意味着,在您终止缓冲区后
int rx_length = read(serial, &rx, MAX_TXRX_BUF);
rx
中没有有效的C字符串。您需要这样做:
char rx[MAX_TXRX_BUF + 1]; // extra space for terminator
ssize_t rx_length = read(serial, rx, MAX_TXRX_BUF);
if (rx_length >= 0) {
rx[rx_length] = '\0';
// use rx here
// if rx_length == 0, handle EOF
} else {
// read error
}
尽管我不知道为什么输出会发生变化,但我预测,如果您将两条printf
语句放在我的//use rx here
位置,它们将始终打印相同的内容
注意:像您使用&rx
一样,获取整个阵列的地址几乎总是一个错误。在大多数情况下,为了引用C中的数组,您实际需要的是第一个元素的地址,这是您通过rx
得到的。(由于太过繁琐和切题而无法进入本文,read
不关心您提供的是这两个元素中的哪一个,但在其他情况下,它可能会导致微妙的错误。因此,在C中的最佳实践是即使在不重要的情况下也使用第一个元素的地址;在您指定(需要整个阵列的地址。)您好,谢谢您的回复和建议。我已经添加了您的更改,但即使我将两个printf放在您告诉我的地方,有时第二个printf的输出也会损坏,如上图所示。我不知道为什么,这很奇怪。rx定义为无符号字符rx[MAX_TXRX_BUF];(1) 您是否也将rx更改为无符号字符rx[MAX\u TXRX\u BUF+1]
?(2) 在valgrind
下运行您的程序,它是否报告任何错误?如果是,修复它们;这让问题消失了吗?你好@zwol,谢谢你的提示。我还将rx改为无符号字符rx[MAX_TXRX_BUF+1],但同样的问题也发生了。我将与valgrind核实,看看它是否报告任何错误。目前我还没有解决这个问题。我也在遵循其他用户的一些建议,例如,在出现错误字符时打印错误字符。通过打印错误的字符,我发现它是空的。如果我找到其他有用的信息,我会把它们贴在这里。感谢您的时间。在应用zwol的修复程序后,您可能试图输出超出ASCII范围的二进制文件。它可能会试图将其解释为utf-8并感到困惑。那个钻石问号符号就是一个标志。试试:void prt(unsigned char*buf,int len){unsigned int chr;for(;len>0;--len,++buf){chr=*buf;if((chr>=0x20)&&(chr)你把rx声明为什么?它是字符还是单词还是长?“下面我给你看输出……”——你的输出看起来是假的。在“正确”输出中,为什么第二行没有冒号?在“错误”中输出,“串行读取:”从何而来,而不是printf()中的“字节读取:”呢?Hello@sawdust我复制它时犯了一个错误,我用相同的输出更正了这个问题。Hello@Baddack它被声明为char rx[MAX_TXRX_BUF];