mr.*_*ody 1 embedded operating-system stm32 dma
DMA 芯片对 5 字节这样的小数据包有效吗?
我正在使用 STM32 开发一个嵌入式项目,我使用 DMA 接收 3 字节数据包,但是当使用 DMA 传输 5 字节数据包时,我没有立即在接收端获取数据包,但是当使用正常传输时,我更快地获取数据包。
那么我们可以说DMA对小数据包无效吗?
使用 DMA 进行接收的问题是 DMA 传输中断发生,然后 DMA 缓冲区(如果已满和/或半满),如果数据包的接收未填充缓冲区以达到半或全传输阈值,您将无法获得用于指示数据可用性的中断。
因此,假设您的接收器有 6 字节 DMA 缓冲区并在半传输和全传输时产生中断,您发送一个 3 字节的数据包,您将在每个数据包的末尾得到一个中断。如果您发送一个 5 字节的数据包,您将收到前三个字节的中断,然后接下来的两个字节将无限期地留在缓冲区中,直到还有一个字节(来自下一个数据包)到达。
因此,这实际上不是“小数据包”的问题,而是数据包与 DMA 缓冲区对齐的问题。事实上,这甚至不是“数据包”的问题——如果数据是一个流,那么当数据流停止时,如果它恰好不是 DMA 缓冲区大小的倍数,你最终会遇到同样的问题。
此外,即使数据包是 DMA 缓冲区大小的精确倍数,如果您在链路上丢失数据,您将不再与缓冲区对齐并会遇到相同的问题。
这种情况下的解决方案是在每次接收 DMA 半/全传输时设置一个计时器以用作超时。超时通常设置为比传输一半缓冲区所花费的时间多一点(假设您使用半/全传输以允许双重或“乒乓”缓冲),因此如果缓冲区一半/没有实现充分转移,计时器期满,计时器处理程序中检索数据已被转移。当DMA半/全传输中断确实发生时,您需要考虑在定时器中断中已经检索到的数据,并且只检索新数据。
因此,您将实现一个驱动程序,其中在任何 DMA 半传输、全传输或定时器中断时从缓冲区检索数据,并且在定时器处理程序中,您维护一个计数或检索到的最后一个缓冲区位置的索引,以便在一半或全部传输您只检索新数据。
如果您的缓冲区很长而您的数据包很小,并且数据没有流式传输,则您可能会在 DMA 中断之间获得多个定时器中断。在这种情况下,您可能会使超时时间小于 DMA 缓冲区填充时间。最佳解决方案可能取决于正在传输的数据的性质以及您可以承受的延迟。
如果你能维持一个字符一个中断的中断率,那么避免DMA接收数据总是更简单,但它永远不会“无效”,只是更复杂。您的问题不是小型 DMA 传输无效,而是您的实现不是最佳的。