Перейти к содержанию

Почему DMA1 на STM32H743 не передаёт данные из буфера?

Обновлено Редакция GAW

У большинства STM32 обычная SRAM начинается с адреса 0x2000 0000, и туда компоновщик кладёт все переменные. У STM32H742/743/750 по этому адресу находится DTCM-RAM — память, тесно связанная с ядром, — и если скрипт компоновщика размещает данные там, в DTCM попадёт и буфер DMA. А контроллеры DMA1 и DMA2 до неё не дотягиваются.

Кто куда может обращаться

Таблица 3 RM0433 перечисляет пути от ведущих шин к ведомым. Для буфера DMA важны четыре строки:

ПамятьАдрес (RM0433, табл. 7)Кэшируется по умолчаниюDMA1, DMA2BDMA
DTCM-RAM0x2000 0000 – 0x2001 FFFFнет, доступ мимо кэшанетнет
AXI SRAM0x2400 0000 – 0x2407 FFFFда, write-backданет
SRAM1, SRAM2, SRAM3 (D2)0x3000 0000 – 0x3004 7FFFда, write-backданет
SRAM4 (D3)0x3800 0000—дада

ST сама советует SRAM1 и SRAM2 как буферы DMA домена D2, SRAM3 — для Ethernet и USB, SRAM4 — для BDMA. SRAM4 — единственная из перечисленных памятей, куда достают и BDMA, и DMA1 с DMA2, так что общий буфер для них кладут туда.

Как перенести буфер

  1. В скрипте компоновщика описать область, например RAM_D2 (rw) : ORIGIN = 0x30000000, LENGTH = 128K — это SRAM1 до 0x3001 FFFF, — и секцию .dma_buffer в ней.
  2. Пометить буфер атрибутом:
// DMA1/DMA2 cannot reach DTCM on STM32H743: place the buffer in D2 SRAM
__attribute__((section(".dma_buffer"), aligned(32))) static uint8_t rx_buf[512];
  1. Перед использованием SRAM1–SRAM3 включить их тактирование — по RM0433 оно выключено после сброса; подробности в ответе «Тактирование SRAM1–SRAM3 на STM32H743».
  2. Решить вопрос с кэшем: SRAM1–SRAM3 и AXI SRAM кэшируются, в отличие от DTCM. Как выделить некэшируемую область, разобрано в ответе «Некэшируемая область для DMA через MPU».

Выравнивание по 32 байта — размер строки кэша Cortex-M7 — избавит от проблем с соседними переменными при обслуживании кэша. Объёмы памяти разных линеек H7 — на странице STM32H7, устройство потоков DMA — в термине DMA.

Похожие вопросы

Как узнать, куда компоновщик положил буфер?

Посмотреть адрес переменной в отладчике или в map-файле сборки. Адрес 0x2000 xxxx у STM32H743 — это DTCM, 0x2400 xxxx — AXI SRAM, 0x3000 xxxx — SRAM1–SRAM3, 0x3800 xxxx — SRAM4. У других STM32 0x2000 0000 — обычная SRAM, поэтому привычный по F1 или F4 код «молча» перестаёт работать на H7.

Можно ли оставить буфер в DTCM и использовать MDMA?

Да: MDMA — единственный контроллер DMA, у которого по RM0433 есть путь к DTCM через порт AHBS ядра. Но MDMA устроен иначе, чем DMA1 и DMA2, и подключение периферии к нему сложнее; обычно проще перенести буфер.

Нужно ли что-то делать с кэшем, если буфер в AXI SRAM?

Да: AXI SRAM кэшируется, и при включённом D-cache ядро и DMA могут видеть разные данные. Либо обслуживают кэш — clean перед передачей и invalidate перед чтением, — либо выделяют под буферы некэшируемую область через MPU. DTCM мимо кэша работает, поэтому там этой проблемы не было.

Источники

  1. STMicroelectronics. RM0433 Reference manual STM32H742, STM32H743/753 and STM32H750 Value line, Rev 9 — табл. 7 Memory map and default device memory area attributes: DTCM 0x2000 0000 – 0x2001 FFFF, AXI SRAM 0x2400 0000 – 0x2407 FFFF, SRAM1 0x3000 0000 – 0x3001 FFFF, SRAM2 0x3002 0000 – 0x3003 FFFF, SRAM3 0x3004 0000 – 0x3004 7FFF, тип Normal, кэш write-back, write allocate; табл. 3 Bus-master-to-bus-slave interconnect: к ITCM и DTCM имеют путь только Cortex-M7 (шины ITCM и DTCM) и MDMA через AHBS; к AXI SRAM — ядро по AXIM, MDMA, DMA1, DMA2, DMA2D, LTDC и другие, но не BDMA; к SRAM1–SRAM3 — ядро, DMA1, DMA2 и другие ведущие D2, но не BDMA; к SRAM4 — ядро по AXIM, MDMA, DMA1, DMA2 и BDMA; разд. 2.4: AXI SRAM с адреса 0x2400 0000 доступна всем ведущим, кроме BDMA; SRAM1 — 0x3000 0000, SRAM2 — 0x3002 0000, SRAM3 — 0x3004 0000, их рекомендуется использовать как буферы DMA домена D2, SRAM3 — для Ethernet и USB; SRAM4 — 0x3800 0000, для буферов BDMA домена D3; DTCM-RAM по адресу 0x2000 0000 доступна ядру и MDMA через ведомую шину AHBS
  2. Arm. Cortex-M7 Processor Technical Reference Manual r1p2 (DDI 0489F), разд. «TCM interfaces», «AHBS interface» — TCM подключены к ядру собственными интерфейсами; внешний DMA получает доступ к TCM только через ведомый порт AHBS ядра; доступ к TCM идёт мимо кэша

Нашли ошибку?