处理UART DMA环形缓冲的竞态,核心是保证中断处理与主循环对缓冲索引的访问原子性。建议:1) 在空闲中断(IDLE)中,读取DMA的NDTR寄存器计算当前写入位置,并立即更新软件写索引(如rx_write_idx),同时用临界区(如关中断或使用__disable_irq/__enable_irq)保护对索引的修改,防止半满中断同时更新。2) 半满中断(HT)触发时,只更新一个独立的半满标志或计数,不直接修改写索引,由主循环或空闲中断统一处理。3) 主循环读取数据时,使用volatile修饰索引变量,并先读写索引再读数据,确保一致性。实操建议:优先使用空闲中断作为帧结束信号,半满中断仅用于搬运数据到更大的应用缓冲区,避免在中断中做复杂逻辑。若使用HAL库,注意其DMA回调中已隐含对NDTR的读取,需在回调外自行加锁。测试时可用逻辑分析仪观察两个中断的时序,确保无数据覆盖。
mcuku 阿沐 · 2026-08-27