【发布时间】:2021-10-20 19:33:44
【问题描述】:
我正在使用 STM32F7 设备开发一个嵌入式项目,编写裸机 C。
我希望能够在程序中的任何时候将数据发送到 UART 以进行调试,而不会在发送数据时阻塞。我正在使用 DMA 来尽量减少用于此的 CPU 时间。
目前我正在将数据填充到 FIFO 队列中,然后发起 DMA 请求,将数据直接从 FIFO 队列发送到 UART。
这个问题是我无法设置 DMA 从 FIFO 缓冲区的开始和结束读取,如果 FIFO 的中间未使用并且消息从缓冲区的末尾换行开始吧。
解决这个问题的两个方法是设置第一个 DMA 请求从 FIFO 的头部读取到缓冲区的末尾,然后一旦完成,从缓冲区的开头读取到缓冲区的尾部先进先出。
另一种方法是 memcpy() 取出要发送到另一个缓冲区的字节,它们都是顺序的,然后发起一个 DMA 请求以一次发送所有数据。
这两种方法都可能有效,但我正在寻找有关最佳方法的见解。
【问题讨论】:
-
虽然这需要意见,这可能会导致这个问题的结束,这就是我的想法。将字节复制到单独的缓冲区中似乎比不使用 DMA 并使用中断更昂贵。这样您就可以使用循环缓冲区。 -- 但是,如果任何缓冲区已满,您将需要阻塞,并且您不想丢失任何数据。
-
你需要一个足够大的循环 FIFO,不会溢出
-
@thebusybee,并非总是如此,有时通过
memcpy()进行复制比 DMA 快很多。实际上,似乎人们完全误解了 DMA 的用途(剧透:在许多情况下不是为了速度)。附注:bounce buffers (memcpy()+ DMA) 技术用于特殊情况。 -
我并没有说使用 DMA 更快,相反。 OP 的第二个想法包括
memcpy()和 DMA,这显然是过度设计的。所以我建议不要使用 DMA。