3、FIFO概念引入:为什么需要FIFO?FIFO在UART中的作用与优势
3.1 从“单字节轮询”到“数据堆积”的痛点
在早期的UART驱动设计中,最常见的模式是单字节轮询(Polling)。CPU需要不断读取UART状态寄存器,判断是否有新数据到达,然后立即读取数据寄存器。这种模式在低速、低数据量的场景下尚可工作,但随着通信速率提升,其弊端迅速暴露:
- CPU占用率极高:CPU必须频繁轮询状态位,无法处理其他任务。
- 响应延迟不可控:如果CPU被更高优先级任务打断,可能错过数据。
- 数据丢失风险:当数据到达速率超过CPU读取速率时,后续数据会覆盖未读取的数据寄存器。
核心矛盾:UART外设的硬件接收速率与CPU软件读取速率之间存在速度鸿沟。单字节缓冲无法有效解耦这两个速率。
3.2 FIFO的引入:硬件级的数据缓冲队列
FIFO(First In, First Out)是一种硬件实现的先进先出数据缓冲器。在UART中,FIFO被嵌入到收发路径上,作为CPU与UART移位寄存器之间的中间存储层。其核心思想是:让硬件自动暂存多个字节,减少CPU的干预频率。
下图展示了引入FIFO前后UART接收路径的架构对比:
3.3 FIFO在UART中的核心作用
FIFO的引入从根本上改变了UART驱动的数据流模型。以下是其核心作用:
| 作用维度 | 详细说明 | 对驱动开发的影响 |
|---|---|---|
| 速率解耦 | 允许UART以硬件速率连续接收数据,CPU以软件速率间歇读取 | 驱动不再需要逐字节同步,可设计为批量处理模式 |
| 中断聚合 | 将多次单字节中断合并为一次批量中断 | 显著降低中断频率,减少上下文切换开销 |
| 数据防丢 | 在CPU响应中断前,FIFO可暂存多个字节 | 驱动有更充裕的时间处理数据,降低溢出风险 |
| 时序容错 | 容忍CPU响应延迟的微小波动 | 驱动对实时性要求降低,设计更灵活 |
3.4 FIFO带来的关键优势
从驱动开发的实际角度,FIFO提供了以下可量化的优势:
- 中断次数减少 80%~95%:以16字节FIFO为例,原本需要16次中断,现在只需1次。
- CPU负载降低:批量读取减少了寄存器访问次数和函数调用开销。
- 数据吞吐量提升:在相同波特率下,有效数据传输率更高。
- 软件架构简化:驱动逻辑从“逐字节紧急处理”变为“按块从容处理”。
驱动开发提示:FIFO并不是越大越好。过大的FIFO会增加数据延迟(Latency),在实时性敏感的场景下需要权衡。通常UART FIFO深度为16字节或32字节,驱动需要根据应用场景配置合适的触发阈值。
3.5 FIFO触发阈值:驱动与硬件的协作点
FIFO本身只是存储介质,真正让FIFO发挥价值的是触发阈值(Trigger Level)。驱动通过配置FIFO触发阈值,决定“当FIFO中累积多少字节时产生中断”。这是FIFO管理策略的核心参数:
3.6 常见FIFO深度与触发配置
不同UART硬件IP的FIFO深度和可配置触发阈值不同。以下是业界常见配置:
| UART IP | FIFO深度 | 可配置触发阈值 | 典型应用场景 |
|---|---|---|---|
| 16550A(PC标准) | 16字节 | 1, 4, 8, 14 | 传统串口、工业控制 |
| STM32 USART | 16字节 | 1/4, 1/2, 3/4, 满 | 嵌入式MCU、IoT设备 |
| Zynq UART | 64字节 | 1~63 可编程 | FPGA SoC、高速通信 |
| NXP LPUART | 16字节 | 1~15 可编程 | 低功耗嵌入式系统 |
常见误区:不要认为启用FIFO就一定能提升性能。如果触发阈值设置过高(如14字节),在低数据率场景下会导致CPU长时间得不到数据,增加响应延迟。驱动开发者需要根据波特率和应用实时性要求动态调整触发阈值。
3.7 本章小结
FIFO是UART驱动从“低效轮询”迈向“高效中断驱动”的关键硬件基础。它通过硬件级的缓冲队列,实现了:
- 速率解耦:硬件接收与软件读取不再强同步。
- 中断聚合:减少中断次数,降低CPU负载。
- 数据保护:提供容错空间,降低丢失风险。