首页 > 代码库 > UART Receive FIFO and Receive Timeout
UART Receive FIFO and Receive Timeout
为什么UART要有FIFO?
现代的CPU运转速度越来越快,UART的波特率通常达不到10M,在没有FIFO的情况下,每次填充数据给UART 或者 从UART取数据都会占用CPU的时间,这是极大的浪费。因而UART在硬件上设置了FIFO用作数据发送和接受的缓冲区。每次CPU要填充数据,把数据填充到UART的TX FIFO里面去了,每次CPU要取数据,从UART的RX FIFO把数据取出来。总之,FIFO作为缓冲区的存在减轻了CPU的负担。
有了FIFO后RX对数据的处理是怎样的?
一般而言,当RX FIFO 接受到数据达到 RX FIFO设置的触发级别时,产生一个中断给CPU,CPU进入中断处理函数将数据取出来。考虑到这样的一种情况,如果有一次传输的数据不是RX FIFO触发级别的整数倍的时候,就会造成最后的那部分数据够不到RX FIFO的触发级别,怎么办,RX FIFO的这部分数据还能取出来吗?
下面考虑两种方法:
1, 将RX FIFO触发级别设置成1,这样每次RX FIFO接受到一个数据就会触发一个中断,不可能存在RX FIFO的数据不够触发级别的情况,因而只要RX FIFO中只要有数据,CPU都能知道并能进行相应的处理。但是这样和没有FIFO区别大吗?很小,CPU的负载太重,每接受一个数据都会产生一个中断。
2,设置RX timeout中断,通过使能该中断,并设置一个timeout值用以确定自从上次接受到数据为止的多长时间里面再也接受不到数据的时候产生RX timeout中断。
目前我们公司的UART的RX timeout中断应该有些问题,使能timeout中断后,在UART没有接受到任何数据的时候,它依然以一定的时间产生这个timeout中断,这是不正常的。
# date && cat /proc/interrupts Fri Jan 2 04:20:52 UTC 1970 CPU0 0: 1680 SIRFINTC sirfsoc_timer0 6: 3 SIRFINTC SGX ISR 8: 0 SIRFINTC prima2-dsp 10: 1 SIRFINTC ci13xxx_sirf 11: 0 SIRFINTC ci13xxx_sirf 12: 0 SIRFINTC sirfsoc_dma 13: 35 SIRFINTC sirfsoc_dma 14: 0 SIRFINTC sirfsoc-vip 18: 22799 SIRFINTC sirfsoc-uart 24: 26 SIRFINTC b00e0000.i2c 25: 13 SIRFINTC b00f0000.i2c 30: 28322 SIRFINTC SIRFSOC-FB 32: 0 SIRFINTC sirfsoc_pwrc_int 33: 0 SIRFINTC sirfsoc_tsc 34: 0 SIRFINTC sirfsoc_adc 38: 8035 SIRFINTC mmc0, mmc1 39: 52 SIRFINTC mmc2, mmc3 52: 0 SIRFINTC sysrtc.11 128: 0 sirf-gpio-irq ft5x0x_ts 129: 0 sirf-gpio-irq extcon-gpio IPI0: 0 CPU wakeup interrupts IPI1: 0 Timer broadcast interrupts IPI2: 0 Rescheduling interrupts IPI3: 0 Function call interrupts IPI4: 0 Single function call interrupts IPI5: 0 CPU stop interrupts IPI6: 0 CPU backtrace Err: 0 # date && cat /proc/interrupts Fri Jan 2 04:21:46 UTC 1970 CPU0 0: 1729 SIRFINTC sirfsoc_timer0 6: 3 SIRFINTC SGX ISR 8: 0 SIRFINTC prima2-dsp 10: 1 SIRFINTC ci13xxx_sirf 11: 0 SIRFINTC ci13xxx_sirf 12: 0 SIRFINTC sirfsoc_dma 13: 35 SIRFINTC sirfsoc_dma 14: 0 SIRFINTC sirfsoc-vip 18: 25674 SIRFINTC sirfsoc-uart 24: 26 SIRFINTC b00e0000.i2c 25: 13 SIRFINTC b00f0000.i2c 30: 31779 SIRFINTC SIRFSOC-FB 32: 0 SIRFINTC sirfsoc_pwrc_int 33: 0 SIRFINTC sirfsoc_tsc 34: 0 SIRFINTC sirfsoc_adc 38: 8085 SIRFINTC mmc0, mmc1 39: 52 SIRFINTC mmc2, mmc3 52: 0 SIRFINTC sysrtc.11 128: 0 sirf-gpio-irq ft5x0x_ts 129: 0 sirf-gpio-irq extcon-gpio IPI0: 0 CPU wakeup interrupts IPI1: 0 Timer broadcast interrupts IPI2: 0 Rescheduling interrupts IPI3: 0 Function call interrupts IPI4: 0 Single function call interrupts IPI5: 0 CPU stop interrupts IPI6: 0 CPU backtrace Err: 0可以看到它一分钟产生了2000+个中断,太不正常。
通过调查学习发现:
1, 什么时候才会有RX timeout中断
- 使能了RX tiemout中断和设置了timeout的值
- RX FIFO 数据非空,并且在设定的时间内没有接受到新的数据且规定时间内RX FIFO的数据并没有发生被读空,它才产生RX timeout中断
2,什么时候清空该中断
- 进入中断处理函数,清理该中断
- 在中断处理函数中将RX FIFO的数据取至空
所以通过设置RX timeout中断和设置RX threshold中断,可以有效的应对IO方式的数据接受工作。
- 通过threshold中断搬运数据
- 通过timeout中断搬运数据