Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-LINUX中串口读取的不一致性_C_Linux_Serial Port_Termios - Fatal编程技术网

C-LINUX中串口读取的不一致性

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

我在使用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 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];