简体   繁体   English

Ubuntu C Uart 通信丢失第一个字节

[英]Ubuntu C Uart communication lost first byte

I do a new summary,do more tests,and post here https://forums.developer.nvidia.com/t/jetson-nx-uart-communiation-lost-first-byte/234877我做了一个新的总结,做更多的测试,并在这里发布https://forums.developer.nvidia.com/t/jetson-nx-uart-communiation-lost-first-byte/234877


I write a uart software using c++ on Jetson Nx(Ubuntu OS) to communicate with a PC.我在 Jetson Nx(Ubuntu OS)上使用 c++ 编写了一个 uart 软件来与 PC 通信。 On PC there's a uart simulator to send data at a period of one second, data is:EB90021112131415161718191A1B1C1D1E1F202122232425262728292A as show below: PC端有一个uart模拟器,每1秒发送一次数据,数据为:EB90021112131415161718191A1B1C1D1E1F202122232425262728292A如下图:

enter image description here在此处输入图像描述

When my software receive the data, sometimes it will lost the first byte "EB", as show like this:当我的软件接收数据时,有时会丢失第一个字节“EB”,如下所示:

90021112131415161718191A1B1C1D1E1F202122232425262728292A 90021112131415161718191A1B1C1D1E1F202122232425262728292A

while sometimes it won't lost the first byte EB.而有时它不会丢失第一个字节 EB。

Besides, I tried a python software to receive data from uart on Jetson Nx, it always works OK.此外,我尝试了一个 python 软件从 Jetson Nx 上的 uart 接收数据,它总是工作正常。

My c code is as below.我的 c 代码如下。

int TestUart(const char * portName, int nSpeed, int nBits, char nEvent, int nStop);

void main(){
    TestUart("/dev/ttyTHS0",9600,8,'N',1);
}


int TestUart(const char * portName, int nSpeed, int nBits, char nEvent, int nStop)
{

    int Port = open(portName, O_RDWR | O_NOCTTY);

    tcflush(Port, TCIFLUSH);
    tcflush(Port, TCIOFLUSH);

    usleep(500000);

    if (Port == -1)
    {
        printf("UART.cpp : Unable to open port.");
        return -1;
    }
    else
    {
        printf("UART.cpp : Port opened. Setting Port options...");
    }

    int fd = Port;

    struct termios newtio, oldtio;
    if (tcgetattr(fd, &oldtio) != 0)
    {
        perror("SetupSerial 1");
        return -1;
    }
    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag |= CLOCAL | CREAD;

    newtio.c_cflag &= ~CSIZE;
    switch (nBits)
    {
    case 7:
        newtio.c_cflag |= CS7;
        break;
    case 8:
        newtio.c_cflag |= CS8;
        break;
    }

    switch (nEvent)
    {
    case 'O':
    case 'o':
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        break;
    case 'E':
    case 'e':
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~PARODD;
        break;
    case 'N':
    case 'n':
        newtio.c_cflag &= ~PARENB;
        break;
    }

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

    newtio.c_cflag &= ~CRTSCTS;
    newtio.c_iflag &= ~(IXON | IXOFF | IXANY);

    if (nStop == 1)
    {
        newtio.c_cflag &= ~CSTOPB;
    }
    else if (nStop == 2)
    {
        newtio.c_cflag |= CSTOPB;
    }
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 1;


    newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    newtio.c_oflag &= ~OPOST;
    if ((tcsetattr(fd, TCSANOW, &newtio)) != 0)
    {
        perror("com set error");
        return -1;
    }
    tcflush(fd, TCIFLUSH);

    int num = 0;

    char rx_data[256];

    while(1)
    {
        int m_curPacket_length = read(Port, rx_data,256);
        tcflush(Port, TCIFLUSH);
        tcflush(Port, TCIOFLUSH);

        printf("    Data %d [port = %s,length = %d]: ",++num,portName,m_curPacket_length);
        for (int i = 0; i < m_curPacket_length; i++) {
            printf("%X ", rx_data[i]);
        }
        printf("\n");
    }

    printf("set UART port paramster done!\n");
    return 0;
}

I expect anyone can help me to find the bug.我希望任何人都可以帮助我找到错误。 Thanks a lot!非常感谢!

Besides, when I set non-blocking mode with setting VTIME=0 and VMIN=0, there is no byte loss.此外,当我通过设置 VTIME=0 和 VMIN=0 设置非阻塞模式时,没有字节丢失。



Thanks for your advice!谢谢你的建议!

1 On Jetson Nx, it really have a different result as I mentiond in the problem. 1 在 Jetson Nx 上,结果确实与我在问题中提到的不同。 May be it's the difference of the handware?可能是硬件的差异? I add more hardware info on my main question borad.我在我的主要问题板上添加了更多硬件信息。

This (poorly formated) result does not have any resemblance to the single line that you claim that you get.此(格式不正确的)结果与您声称获得的单行没有任何相似之处。 More importantly there are no "missing" bytes as all 29 bytes of the message are always received and displayed, although there is an extended-sign issue with the first two bytes.更重要的是,没有“丢失”的字节,因为消息的所有 29 个字节总是被接收和显示,尽管前两个字节存在扩展符号问题。

2 Really igore the empty lines, that's just a try. 2 真的忽略空行,那只是一个尝试。

Again your description of the results that you claim your code produces is inaccurate and misleading.同样,您对您声称代码产生的结果的描述不准确且具有误导性。 You neglect to mention that your code will produce extraneous text while incessantly polling the system:您没有提到您的代码会在不断轮询系统时产生无关的文本:

3 Change as below, remains the same problem. 3 如下更改,问题依旧。

  • bzero(&newtio, sizeof(newtio)); bzero(&newtio, sizeof(newtio));
  • newtio = oldtio; newtio = oldtio; 4 Below changed still no effect. 4 下面改了还是没效果。
  • char rx_data[256]; char rx_data[256];
  • unsigned char rx_data[256];无符号字符 rx_data[256]; 5 Below changed will be print as follow: 5 以下更改将打印如下:
  • newtio.c_cc[VTIME] = 0; newtio.c_cc[VTIME] = 0;
  • newtio.c_cc[VMIN] = 1; newtio.c_cc[VMIN] = 1;
  • newtio.c_cc[VTIME] = 1; newtio.c_cc[VTIME] = 1;
  • newtio.c_cc[VMIN] = 29; newtio.c_cc[VMIN] = 29; print result:打印结果:
Data 1 [port = /dev/ttyUSB0,length = 57]:90021112131415161718191A1B1C1D1E1F202122232425262728292AEB90021112131415161718191A1B1C1D1E1F202122232425262728292A
Data 2 [port = /dev/ttyUSB0,length = 57]:90021112131415161718191A1B1C1D1E1F202122232425262728292AEB90021112131415161718191A1B1C1D1E1F202122232425262728292A

Still lost the first 'EB'仍然失去了第一个'EB'

When my software receive the data, sometimes it will lost the first byte "EB", as show like this:当我的软件接收数据时,有时会丢失第一个字节“EB”,如下所示:

90021112131415161718191A1B1C1D1E1F202122232425262728292A 90021112131415161718191A1B1C1D1E1F202122232425262728292A

while sometimes it won't lost the first byte EB.而有时它不会丢失第一个字节 EB。
... ...
My c code is as below.我的 c 代码如下。
... ...

Assuming that the Jetson Nx is not horribly slow in comparison to the 9600 baud, executing your code as posted (on a PC) produces the following results for me:假设 Jetson Nx 与 9600 波特率相比并不慢得可怕,执行您发布的代码(在 PC 上)会为我产生以下结果:

$ ./a.out
UART.cpp : Port opened. Setting Port options...    Data 1 [port = /dev/ttyUSB0,length = 1]: FFFFFFEB 
    Data 2 [port = /dev/ttyUSB0,length = 1]: FFFFFF90 
    Data 3 [port = /dev/ttyUSB0,length = 1]: 2 
    Data 4 [port = /dev/ttyUSB0,length = 1]: 11 
    Data 5 [port = /dev/ttyUSB0,length = 1]: 12 
    Data 6 [port = /dev/ttyUSB0,length = 1]: 13 
    Data 7 [port = /dev/ttyUSB0,length = 1]: 14 
    Data 8 [port = /dev/ttyUSB0,length = 1]: 15 
    Data 9 [port = /dev/ttyUSB0,length = 1]: 16 
    Data 10 [port = /dev/ttyUSB0,length = 1]: 17 
    Data 11 [port = /dev/ttyUSB0,length = 1]: 18 
    Data 12 [port = /dev/ttyUSB0,length = 1]: 19 
    Data 13 [port = /dev/ttyUSB0,length = 1]: 1A 
    Data 14 [port = /dev/ttyUSB0,length = 1]: 1B 
    Data 15 [port = /dev/ttyUSB0,length = 1]: 1C 
    Data 16 [port = /dev/ttyUSB0,length = 1]: 1D 
    Data 17 [port = /dev/ttyUSB0,length = 1]: 1E 
    Data 18 [port = /dev/ttyUSB0,length = 1]: 1F 
    Data 19 [port = /dev/ttyUSB0,length = 1]: 20 
    Data 20 [port = /dev/ttyUSB0,length = 1]: 21 
    Data 21 [port = /dev/ttyUSB0,length = 1]: 22 
    Data 22 [port = /dev/ttyUSB0,length = 1]: 23 
    Data 23 [port = /dev/ttyUSB0,length = 1]: 24 
    Data 24 [port = /dev/ttyUSB0,length = 1]: 25 
    Data 25 [port = /dev/ttyUSB0,length = 1]: 26 
    Data 26 [port = /dev/ttyUSB0,length = 1]: 27 
    Data 27 [port = /dev/ttyUSB0,length = 1]: 28 
    Data 28 [port = /dev/ttyUSB0,length = 1]: 29 
    Data 29 [port = /dev/ttyUSB0,length = 1]: 2A 

This (poorly formated) result does not have any resemblance to the single line that you claim that you get.此(格式不正确的)结果与您声称获得的单行没有任何相似之处。
More importantly there are no " missing " bytes as all 29 bytes of the message are always received and displayed, although there is an extended-sign issue with the first two bytes.更重要的是,没有“丢失”字节,因为消息的所有 29 个字节总是被接收和显示,尽管前两个字节存在扩展符号问题。


Besides, when I set non-blocking mode with setting VTIME=0 and VMIN=0, there is no byte loss.此外,当我通过设置 VTIME=0 和 VMIN=0 设置非阻塞模式时,没有字节丢失。

Again your description of the results that you claim your code produces is inaccurate and misleading.同样,您对您声称代码产生的结果的描述不准确且具有误导性。 You neglect to mention that your code will produce extraneous text while incessantly polling the system:您没有提到您的代码会在不断轮询系统时产生无关的文本:

UART.cpp : Port opened. Setting Port options...    Data 1 [port = /dev/ttyUSB0,length = 0]: 
    Data 2 [port = /dev/ttyUSB0,length = 0]: 
    Data 3 [port = /dev/ttyUSB0,length = 0]: 
    Data 4 [port = /dev/ttyUSB0,length = 0]: 
    Data 5 [port = /dev/ttyUSB0,length = 0]: 
    Data 6 [port = /dev/ttyUSB0,length = 0]: 
    Data 7 [port = /dev/ttyUSB0,length = 0]: 
    Data 8 [port = /dev/ttyUSB0,length = 0]: 
    Data 9 [port = /dev/ttyUSB0,length = 0]: 
    Data 10 [port = /dev/ttyUSB0,length = 0]: 
    Data 11 [port = /dev/ttyUSB0,length = 0]: 
    Data 12 [port = /dev/ttyUSB0,length = 0]: 
    Data 13 [port = /dev/ttyUSB0,length = 0]: 
    Data 14 [port = /dev/ttyUSB0,length = 0]: 
    Data 15 [port = /dev/ttyUSB0,length = 0]: 
    Data 16 [port = /dev/ttyUSB0,length = 0]: 
    Data 17 [port = /dev/ttyUSB0,length = 0]: 
    Data 18 [port = /dev/ttyUSB0,length = 0]: 
    Data 19 [port = /dev/ttyUSB0,length = 0]: 
    Data 20 [port = /dev/ttyUSB0,length = 0]: 
    Data 21 [port = /dev/ttyUSB0,length = 0]: 
    Data 22 [port = /dev/ttyUSB0,length = 0]:
    ...

How do manage to sort out the text that indicates received data versus the garbage of no input?如何设法区分指示已接收数据的文本与无输入的垃圾?



Your initialization is flawed because a zeroed-out termios struct is used.您的初始化有缺陷,因为使用了清零的 termios 结构。 See Setting Terminal Modes Properly .请参阅正确设置终端模式

I have tried not zeroed-out termios struct is used, still the same problem remains.我试过不使用清零的 termios 结构,仍然存在同样的问题。

 if (tcgetattr(fd, &newtio);= 0) { perror("SetupSerial 1"); return -1, } //bzero(&newtio; sizeof(newtio));

You've done a poor job of following my advice, since you clearly did not bother to study the linked guide.你没有听从我的建议,因为你显然没有费心去研究链接的指南。
By simply deleting the bzero() statement, you are now using an uninitialized structure, which could be a worse bug and should have generated a compiler warning.通过简单地删除bzero()语句,您现在使用的是未初始化的结构,这可能是一个更严重的错误,应该会生成编译器警告。
The proper correction to your code is (using patch notation):对您的代码的正确更正是(使用补丁表示法):

-    bzero(&newtio, sizeof(newtio));
+    newtio = oldtio;

Your userspace program is not synchronized with UART I/O, so flushing system buffers (discarding I/O data) is prone to inadvertent loss of real data.您的用户空间程序与 UART I/O 不同步,因此刷新系统缓冲区(丢弃 I/O 数据)很容易无意中丢失实际数据。 IOW you're misusing the flush directive IOW 你滥用了 flush 指令

and when no flush as show below, still remains the problem如下图所示,当没有冲洗时,问题仍然存在

In turns out, despite the flaws in your code, I can use your original code to consistently receive the messages of 29 bytes on my PC.事实证明,尽管您的代码存在缺陷,但我可以使用您的原始代码在我的 PC 上持续接收 29 字节的消息。 Although the flaws do not cause any observed misbehavior currently, they must be corrected for reliable and robust code.虽然这些缺陷目前不会导致任何观察到的不当行为,但必须纠正它们以获得可靠和健壮的代码。

I am unable to understand what you are calling " missing bytes ".我无法理解你所说的“丢失的字节”。 Is the sign-extended representation of the first two bytes the problem?前两个字节的符号扩展表示是问题所在吗?
That is simply corrected by using the appropriate type for the receive buffer:这可以通过为接收缓冲区使用适当的类型来简单地纠正:

-    char rx_data[256];
+    unsigned char rx_data[256];

Given that your system is receiving a message of 29 bytes each second, you can improve the efficiency of each read() syscall by trying to fetch a full message.鉴于您的系统每秒接收 29 字节的消息,您可以通过尝试获取完整消息来提高每个read()系统调用的效率。 Try changing the following termios attributes:尝试更改以下 termios 属性:

-    newtio.c_cc[VTIME] = 0;
-    newtio.c_cc[VMIN] = 1;
+    newtio.c_cc[VTIME] = 1;
+    newtio.c_cc[VMIN] = 29;

The program can then read a complete message per syscall:然后程序可以在每个系统调用中读取完整的消息:

$ ./a.out
UART.cpp : Port opened. Setting Port options...
    Data 1 [port = /dev/ttyUSB0,length = 29]: EB 90 2 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 
    Data 2 [port = /dev/ttyUSB0,length = 29]: EB 90 2 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM