如何正确设置应用程序以将USB DMA控制器与STM32H7设备一起使用

1.简介

此常见问题解答涉及在STM32H7设备中启用USB DMA。许多在STM32H7设备中使用USB的客户在激活DMA时会遇到问题。他们注意到的是,在激活DMA之前,一切都很好,USB表现正常。一旦他们启用DMA,一切都会崩溃,这对USB主机和设备来说都很常见:

hpcd.Init.dma_enable=启用;

hhcd.Init.dma_enable=启用;


这个问题与两个可能的根本原因有关:STM32H7上的内存布局和Cortex-M7内核的内部数据缓存(D-cache)。这将在后面详细说明。

总之,可能存在以下问题:

  • 变量和缓冲区被放置在DTCM SRAM中。不幸的是,DTCMSRAM在包括示例在内的一些项目中被设置为默认内存位置。
  • 为DMA缓冲区启用D缓存,缓存和SRAM内存中的不同内容(数据一致性问题)
  • 在将数据写入TX缓冲区后立即启动DMA,没有同步障碍(在最后一次数据写入和DMA启用之间放置__DSB()指令)。

2.可能的根本原因1:STM32H7内存布局

STM32H7设备基本上包含三个域D1、D2和D3。然而,在一些设备(STM32H7A3/7B3和STM32H7B0)中,我们只能找到两个域,其中D1和D2域合并为一个域,即CD域,D3被指定为SRD域。
在本常见问题解答中,我们将研究具有三个域的STM32H7设备的情况。但当考虑到前面解释的对准时,这可以适用于所有其他STM32H7器件。
正如我们之前所解释的,大多数STM32H7器件由三个总线矩阵域(D1、D2和D3)组成,如下图所示。

D1和D2域通过总线桥连接,两者也可以访问D3域中的数据。然而,从D3域到D1或D2域没有连接。
这个数据管理1数据管理2控制器位于D2域中,并且可以访问除ITCM和DTCM RAM(位于0x20000000)之外的几乎所有存储器。这种DMA在大多数情况下都会使用。
BDMA公司控制器位于D3域中,只能访问D3域中的SRAM4和备份SRAM。
多药耐药性控制器位于D1域中,可以访问包括ITCM/DTCM在内的所有存储器。该控制器主要用于处理D1外围设备和域之间的内存传输。
在上图中,我们可以看到USBHS1和USBHS2位于D2域,并且与DTCM RAM没有互连,DTCM RAM是几乎所有USB项目中使用的默认存储器。因此,当启用内部DMA USB时,项目不起作用,因为DMA将无法访问DTCM中的数据缓冲区,并导致DMA传输错误。

3.可能的根本原因2:在启用D-Cache的情况下处理DMA缓冲区

Cortex-M7包含两个内部缓存,用于加载指令的I-Cache和用于数据的D-Cache。D-Cache可能会影响DMA USB传输的功能,因为产品SRAM的默认缓存策略是普通内存(可缓存)。缓存会将新数据保存在内部缓存中,而不会将它们写入SRAM内存。但是,DMA控制器从SRAM存储器而不是D-Cache加载数据。读取数据时也会发生同样的行为,因为USB DMA会更新SRAM中的缓冲区,并且SRAM的内容不会立即对CPU可见,因为CPU会看到以前缓存的数据。这将导致数据一致性问题。
有几种方法可以通过D-cache保持管理USB DMA:
  • 使用缓存维护操作:在启用DMA之前,软件可以请求高速缓存清理操作以将数据写入SRAM,并且在读取之前,软件可请求清理高速缓存并使其无效以与新的SRAM内容重新同步。

  • 禁用部分内存的D-Cache:使用MPU将DMA缓冲区更改为不可缓存(设备模式)

  • 全局禁用D缓存:但这可能会导致性能损失,因此不建议这样做。

4.解决方案:STM32H743I-EVAL、STM32CubeMX和STM32CubeIDE的示例

为了综合前面解释的内容,我们在本节中展示了一个使用STM32H743I-EVAL板的示例,但这适用于所有STM32H7设备。

  • 项目创建和生成:在本节中,我们将使用STM32CubeMX创建并生成USB项目。我们将以人机接口设备类(HID)USB HS应用程序为例,但这适用于所有其他USB设备和主机项目。下图显示了应设置的配置:


    在使用您的首选工具(我们在本教程中使用IAR)生成项目后,您可以看到HID应用程序运行良好鼠标通过设备管理器
    现在,我们将启用DMA IP:

    生成项目后,您可以指出枚举丢失,您的笔记本电脑无法再正确检测HID设备。

    STM32CubeMx生成的默认内存分配是DTCM,USB无法访问DTCM,STM32Cube7固件包中的大多数USB应用程序都使用该内存分配。参考相应的参考手册后,您可以在下面找到USB可访问的存储器系统架构部分因此,让我们用另一个可通过USB访问的DTCM存储器来更改DTCM存储器,例如AXI SRAM 0x2400 0000。

    不幸的是,这种配置还不够,但为了示例的目的,我们将应用更简单的解决方案来确认该问题与数据一致性有关。我们将禁用数据缓存,如前所述。




    现在,您可以看到您的HID兼容鼠标设备已被设备管理器很好地枚举。


5.参考文献:

  • 常见问题:DMA无法在STM32H7设备上工作
  • 安4838:管理STM32 MCU中的内存保护单元(MPU)
  • 安4839:STM32F7系列和STM32H7系列上的1级缓存
  • 安4891:STM32Cube的STM32H7x3系统架构和性能软件扩展