UART内部具有一个32字节的接收FIFO,并在该FIFO为四分之一满,一半满,四分之三满和完全满时提供中断。如何确定这些中断中的哪一个应触发我的ISR?需要进行哪些权衡?
注意-该协议涉及32字节(固定长度)的数据包,每10毫秒发送一次。
答案 0 :(得分:4)
这取决于很多事情,最重要的是所支持的最大波特率,还取决于您的应用程序需要多少时间来执行其他任务。
传统环形缓冲区基于逐字节中断工作。但是减少中断数量当然总是很不错的。您多久触发一次可能并不重要。
实现双缓冲区方案更为重要。当然,您应该不开始直接从单个环形缓冲区运行状态机解码。那将变成一场比赛条件的噩梦。
您的主程序应发出信号/禁用UART中断,然后复制整个缓冲区,然后允许中断。理想情况下,缓冲区复制是通过更改指针而不是硬拷贝来完成的。需要对执行此操作的代码进行基准测试,以使其执行速度超过1 / baudrate * 10秒。其中10是:假设UART为8-N-1,则1个开始,8个数据,1个停止。
如果可用,请通过软件环形缓冲区使用DMA。
答案 1 :(得分:1)
给出一个基于数据包的协议和一个UART,当接收到一个以上的字节时中断,请考虑如果接收到数据包的最后一个字节但该最后字节不足以填充FIFO超过阈值,应该怎么办并触发一个中断在接收到一些后续数据包并且FIFO最终填满之前,您的应用程序是否只是不会接收该不完整的数据包?如果另一端正在等待响应并且从不发送另一个数据包怎么办?还是您的应用程序应该轮询UART以检查UART FIFO中是否剩余字节?同时使用中断和轮询接收的字节似乎太复杂了。
使用已实现的基于数据包的协议,UART驱动程序不依赖UART FIFO,而是将UART配置为在单个字节可用时中断。这样,驱动程序将获得每个字节的通知,并且包的最后一个字节不会留在UART的FIFO中。
UART的FIFO可以方便地用于流协议(例如音频或视频数据)。当驱动程序正在接收数据流时,将始终有传入数据来保持填充FIFO。驱动程序可以依靠UART的FIFO来缓冲一些数据。通过在每个中断中处理多个字节并降低中断率,可以提高驱动程序的效率。
由于您的数据包是固定长度的,因此您可以考虑使用UART FIFO。但是请考虑一下,如果由于噪声或其他原因丢失单个字节,驱动程序将如何恢复。我认为,无论数据包是否为固定长度,最好不要依赖FIFO来实现基于数据包的协议。