Data lost issue in Hikey960


#1

I connected a externel device to hikey960 by UART3.
And,the device will send data to hikey960 at regular intervals.

My issue is only 65 bytes of data can be read at a time,
even if i set read count to 8192.

I also connected my externel device to other development boards,
and can get all the data.So, i think perhaps hikey960 has some issue on UART3.

Does anyone have the same problem?
Any suggesitions on it?

Thanks!


#2

What you a describing sounds like normal behaviour for Linux character devices. The contract of read() is that it reads up to count bytes; there’s nothing wrong with it returning fewer than count bytes. The kernel can divide the data coming off the UART into any size it finds convenient.

Code to read a fixed size buffer from a UART should be written as a while loop. Something like:

while (sz > 0) {
    bytes_read = read(fd, p, sz);
    if (bytes_read < 0)
        break;
    p += bytes_read; /* assuming p is char * */
    sz -= bytes_read;
}

To be clear I’m not saying that you are not losing data; what I’m saying that read returning 65 characters at a time is not evidence of losing data. You’d only know if you lost data if the subsequent read() gave discontinuous values.


#3

Do you actually lose data or read all the data but in 64bytes chunks ?
Basically, the size parameter of read function is the max data you want to read not the number of bytes you will effectively get.

If you really loose data, what is the Baudrate and are you using hw flow control ?


#4

Thank you for your suggetions.
I will retry it according to your suggetion,
and update check result to this thick.


#5

Thank you for your reply!
I will retry whether i actually lose data or not.
My Baudrate is 115200 and hw flow control is none.


#6

I had double check this issue on my hikey960 board.
I read uart3 in block mode and print all read data.
The result is actually lose data and not related to the subsequent read() gave discontinuous values.

My uart configuration is as follow:

struct termios tty;
int32_t ret;

ret = tcgetattr(fd, &tty);
if (ret < 0) {
    return ret;
}

tcflush(fd, TCIOFLUSH);

cfsetospeed(&tty, B115200);
cfsetispeed(&tty, B115200);

cfmakeraw(&tty);

tty.c_cflag  |=  CLOCAL | CREAD;
tty.c_cflag &= ~CSIZE;
tty.c_cflag &= ~PARENB;
tty.c_cflag |= CS8 ;
tty.c_cflag &=  ~CSTOPB;

tcsetattr(fd, TCSANOW, &tty);

=============================

Could you kindly give me some suggestions on it?

Best regards
Spring


#7

Before I debugged a bit for UART on HIkey/Hikey960, seems below code works for me:

int serial_port_open(void)
{
        struct termios options;

        serial_port = open(PORT_NAME, O_RDWR | O_SYNC);

        tcgetattr(serial_port, &options_original);
        tcgetattr(serial_port, &options);

        cfsetspeed(&options, B115200);
        cfmakeraw(&options);

       tcsetattr(serial_port, TCSANOW, &options);
       tcflush(serial_port, TCIOFLUSH);
       return serial_port;
 }

#8

I change Baudrate to 4800,and can receive all the data.
It seems that overflow is happened in uart driver.


#9

Have you tried to use “O_SYNC” mode when open UART port? If decrease the baudrate, this might be avoid the data lost in FIFO; but not sure if this can totally ensure the data is not lost. At my side, I found “O_SYNC” is fatal for UART data lost issue…


#10

Thank you for your reply!
This flag is not works for me.