STM32H7 | Portenta H7 DMA 传输(ADC 到内存)期间数据丢失

问题描述 投票:0回答:2

我目前正在研究STM32H747XI (Portenta H7)。我正在使用 DMA1 对 ADC1 进行编程,以 1Msps 的速度获取 16 位数据。

很抱歉,我无法分享我的整个代码,但因此我会尝试尽可能准确地描述我的配置。

我正在使用由 1MHz 定时器触发的 ADC1。 ADC 在连续模式下工作,具有 DMA 循环和双缓冲模式。我尝试了直接模式并使用完整的 FIFO 进行突发。我没有 DMA 错误中断,也没有 ADC 溢出。

我的外围设备正在运行,但我遇到了两个问题。第一个问题,我正在做 8192 uint16_t 的缓冲区,并使用 arduino 函数 USBserial.Write(buf,len) 将其发送到 USB CDC。在这种情况下,USB 传输正常,但缓冲区中缺少一些数据。 DMA 增加内存但不写入。所以我没有丢失样本,但该值是假的(它属于旧缓冲区)。

您可以看到下面的数据图: transfer with buffer of 8192 samples

如果我将缓冲区大小加倍,这个问题就解决了,但另一个问题又出现了。如果数据缓冲区长度超过 16384 字节,则 USB VPC 传输失败。部分数据被删减。我试图通过不同的发送和延迟来解决这个问题,但它不起作用。我还有同样的切口。

这里是具有较长缓冲区的同一脚本的数据图:transfer withe buffer of 16384 sample (32768 byte)

感谢您的帮助。我仍然有空。

arduino stm32 missing-data dma stm32h7
2个回答
0
投票

为了快速检查,请尝试禁用数据缓存。您可能没有正确管理缓存,或者没有在使用 DMA 的内存空间中禁用缓存。 外设不知道缓存,因此您必须手动管理它。在这种情况下,您还必须将缓冲区与缓存行对齐。

参考AN4839


0
投票

我使用的是STM32H750。 DCache 已禁用。我的缓冲区位于 RAM_D1 中。我正在使用CDC。

禁用 USB DMA 后,一切正常。

使用 DMA WireShark 向我展示了 URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 我确实进行了 2-5 次传输,然后就停止了。

我还需要 DMA,因为如果没有 DMA,USB HAL 驱动程序写入函数会占用太多 CPU 周期,并且我的 ADC 流水线会溢出。该问题受到 Windows 主机繁忙程度的影响...不繁忙时,非 DMA 工作。但是,当我的 PC 端应用程序非常繁忙时,串行读取速度会变慢,因此数据会在各个级别的缓冲上进行备份。当PC消耗数据增益时,STM32H7会尝试发回大量数据,而那些非DMA传输会占用太多周期。

这些链接有帮助,

https://community.st.com/t5/stm32-mcus-embedded-software/problem-with-stm32h747-hs-usb-dma/m-p/165464#M9835

https://community.st.com/t5/stm32-mcus/how-to- Correctly-setup-your-application-to-use-usb-dma/ta-p/49522

请注意这一点,

D1 and D2 domains are connected through bus bridges, both can also access data in D3 domain. However, there is no connection from D3 domain to D1 or D2 domain. The DMA1 and DMA2 controllers are located in D2 domain and can access almost all memories with exception of ITCM and DTCM RAM (located at 0x20000000). This DMA is used in most cases. BDMA controller is located in D3 domain and can access only SRAM4 and backup SRAM in D3 domain. MDMA controller is located in D1 domain and can access all memories, including ITCM/DTCM. This controller is mainly used for handling D1 peripherals and memory transfers between domains. In the previous figure, we can see that USBHS1 and USBHS2 are located in D2 domain and have no interconnection with DTCM RAM which is the default memory used in approximately all USB projects. Therefore when enabling the internal DMA USB, projects do not work, as DMA will not be able to access the data buffers placed in DTCM and it results in DMA transfer error.

并且,

CDC known limitations When using this driver with the OTG HS core, enabling DMA mode (define USB_OTG_HS_INTERNAL_DMA_ENABLED in usb_conf.h file) results in data being sent only by multiple of 4 bytes. This is due to the fact that USB DMA does not allow sending data from non word-aligned addresses. For this specific application, it is advised not to enable this option unless required. From: UM1734 User manual STM32Cube USB device library DocID025934 Rev 1

我还没有达到我想要的最终结果,但我可以和目标进行交流

© www.soinside.com 2019 - 2024. All rights reserved.