为什么在 UART RX FIFO 中提供 FIFO 四分之一满、半满、四分之三满中断?他们的用例是什么?

Why are FIFO One-quarter full, Half-full, three-quarter full interrupts provided in a UART RX FIFO? What are their use cases?

我正在实现一个协议解码器,它通过微控制器的 UART 接收字节。 ISR 从 UART 外设获取字节并将其放入环形缓冲区。主循环从环形缓冲区中读取并运行状态机对其进行解码。

UART内部有一个32字节的接收FIFO,当这个FIFO四分之一满、半满、四分之三满和全满时提供中断。我应该如何确定哪些中断应该触发我的 ISR?涉及的权衡是什么?

注意-该协议涉及32字节(固定长度)的数据包,每10ms发送一次。

给定一个基于数据包的协议和一个在接收到超过一个字节时中断的 UART,考虑如果接收到数据包的最后一个字节但最后一个字节不足以填充过去的 FIFO 会发生什么阈值并触发中断。您的应用程序是否只是在接收到一些后续数据包并且 FIFO 最终填满之前才接收到该不完整的数据包?如果另一端正在等待响应并且从不发送另一个数据包怎么办?或者您的应用程序是否应该轮询 UART 以检查 UART FIFO 中剩余的延迟字节?对于接收到的字节同时使用中断和轮询似乎过于复杂。

使用我实现的基于数据包的协议,UART 驱动程序不依赖于 UART FIFO 并将 UART 配置为在单个字节可用时中断。这样,驱动程序会收到每个字节的通知,并且数据包的最后一个字节不会留在 UART 的 FIFO 中。

UART 的FIFO 可以方便流式传输协议(例如音频或视频数据)。当驱动程序接收数据流时,总会有传入的数据不断填充 FIFO。驱动程序可以依靠 UART 的 FIFO 来缓冲一些数据。驱动程序可以通过处理每个中断的多个字节并降低中断率来提高效率。

您可以考虑使用 UART FIFO,因为您的数据包是固定长度的。但是请考虑如果单个字节由于噪音或其他原因而丢失,驱动程序将如何恢复。我认为无论数据包是否固定长度,基于数据包的协议最好不要依赖 FIFO。

这取决于很多因素,最重要的是支持的最大波特率,以及您的应用程序执行其他任务所需的时间。

传统的环形缓冲区在逐字节中断的基础上工作。但是减少中断次数当然总是好的。您让它触发的频率可能并不重要。

实现双缓冲方案更为重要。你当然应该 而不是 开始 运行 状态机直接从单个环形缓冲区解码。那将变成竞争条件的噩梦。

您的主程序应该触发 semaphore/disable UART 中断,然后复制整个缓冲区,然后允许中断。理想情况下,缓冲区复制是通过更改指针而不是硬拷贝来完成的。执行此操作的代码需要进行基准测试,以执行速度快于 1/波特率 * 10 秒。其中10是:1个开始,8个数据,1个停止,假设UART是8-N-1。

如果可用,请在软件环形缓冲区上使用 DMA。