RS232/RS422/RS485 异步通信通常使用一个UART 来发送和接受数据, 用UART 芯片来控制串口的传输。UART芯片内部有一个FIFO缓冲区,用于存储软件驱动程序的输入数据。 FIFO的大小为1、16、64或128个字节,具体取决于UART类型。 FIFO用于通过缓冲数据来提高两个串行端口之间的通信吞吐量。接收和发送FIFO是独立的。

数据流向 (RX)

外部的串口设备------->  UART芯片的FIFO,FIFO数据到达trigger level ,触发中断 --------> driver 读取数据  ---> 拷贝数据到应用层程序

数据流向 (TX)

应用层程序数据------> 拷贝到 driver --------> 拷贝到FIFO,FIFO数据到达trigger level ,触发中断  ---> UART 芯片发出数据 ------>外部的串口设备

android t3 串口丢包问题 串口通信丢包原因_buffer overruns

UART芯片的数据流向

android t3 串口丢包问题 串口通信丢包原因_串口通信丢包_02

由于我的设备上有16个串口,同时进行高速大文件传输,容易发送丢包现象。

一般来说串口通信丢包会有以下原因:

1、CPU本身性能限制 或者 总线的限制 导致中断响应不过来。

   高速  大数据通信时会出现。CPU本身限制 中断响应不过来,这时候一般可以选择更低的波特率、或者更小的封包,或者发包时加一些延时来解决,不过 这些都是应用层的解决方案,在驱动层能做的工作,微乎其微。

2、由于应用程序效率不高,导致CPU loading 过大,持续100%,可能会有中断丢失的现象,也会导致丢包。

     这时候优化程序显的格外重要,减少不必要的printf,printf 是非常耗时的。

3、trigger level 设置不合理

    RX_Trigger 越小,给CPU的中断越多,(这时应该减少封包的大小,降低传输速率,避免丢包发生)

    RX_Trigger 越大,给CPU的中断越少,CPU可能性能更好一些,但是 RX_Trigger 过大,FIFO可能会溢出。

   这是因为 触发中断后,经过“interrupt latency” 中断延迟时间,驱动去读取数据  如果 interrupt latency 小于 1 character time , FIFO 就会溢出。 所以 RX_Trigger 设置的时候要远小于 FIFO的100%

     TX_Trigger 产生中断后发送,就OK , 所以不会有等待的时间 , TX_Trigger 可以设置的稍微大一些,来增加CPU的性能。