STM32F4 在进行 DMA 传输 (RX) 时处理外设错误

STM32F4 Handling peripheral error while making a DMA Transfer (RX)

我正在尝试对 RX 和 TX 使用 DMA 与 UART 外设进行通信。 我正在使用 ST 提供的 HAL 库(使用 STCubeMX 生成)。

我正在处理一个 1.5MBaud 的 UART 通道 - 所以为了不丢失任何数据,我将 DMA 配置为直接模式,带有循环缓冲区,并处理了半传输中断以处理数据,并保持 DMA 在线以获取更多数据。

问题是有时我可以在UART的状态寄存器中看到Frame Error位打开,有时Overrun Error标志也打开。

我可以处理丢失的字节(在结构化数据包上使用 crc),但问题是外围设备停止接收数据 - 但 DMA 不会引发错误或停止传输。

因此,如果我尝试接收数据,并且系统上的标志挂起。

我看到 HAL 提供了一个 __weak 函数来处理 UART_Error,但它从未被调用 - HAL 句柄中的状态保持正常。 看寄存器就知道有问题

我应该如何detect/handle这些错误?

谢谢

出于性能原因,我不使用 HAL,因为它非常笨拙,而且 - imo 也没有提供太多抽象来证明这一点。直接处理硬件并不复杂;甚至更多,因为您仍然必须非常了解发生的事情。正如您已经检测到的那样,HAL 只支持某种方法;一旦你走自己的路,你就会迷路。

您显然遇到了与设置溢出标志类似的问题。发生此类错误后,一般来说,您必须在发生错误后将接收器与发送器字节流重新同步。这将需要使用不在数据包内出现的符号或线路条件的带外信令。帧错误是一个很好的指标,正确同步到符号的开头(起始位)存在问题。

如果线路干净(不是 EMC 问题),应该没有帧错误或数据损坏(除非时序参数不匹配)。

如果使用简单的乒乓球,超时可能就足够了。但是,正确的解决方案取决于协议。一个好的协议设计会考虑传输错误和溢出。

请注意,除了要通知 DMA 传输之外,您还必须启用接收错误中断。但是,如果您使用超时(和乒乓协议),您就可以擦除标志,因为数据显然没有及时到达。如果实际使用错误中断,也要注意竞争条件。