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接收路径的架构对比:

UART接收路径对比:无FIFO vs 有FIFO 无 FIFO 架构 移位寄存器 数据寄存器 CPU 读取 ⚠ 每次只能存1字节 CPU必须频繁轮询 有 FIFO 架构 移位寄存器 FIFO 缓冲区 CPU 批量读取 ✓ 可缓存多个字节 ✓ CPU按需批量读取

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管理策略的核心参数:

FIFO触发阈值与中断行为 FIFO 缓冲区(深度16字节) 触发阈值 (8字节) 数据继续填充 触发中断,CPU读取 当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负载。
  • 数据保护:提供容错空间,降低丢失风险。