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

Режим двойного буфера DMA (double buffer mode)

В кольцевом режиме DMA пишет в один буфер, и программа делит его на половины. В режиме двойного буфера у потока два независимых адреса, и DMA сам переключается между ними. Пока один буфер заполняется, другой можно обработать или даже заменить на новый. Разбираем по RM0090 для STM32F4.

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

Режим двойного буфера DMA (double buffer mode, «пинг-понг») — режим потока DMA, в котором у него два адреса памяти, и в конце каждой передачи они меняются местами. Пока DMA заполняет один буфер, программа обрабатывает другой; переключение происходит аппаратно, без остановки потока.

Как устроено в STM32F4

Режим включается битом DBM в регистре DMA_SxCR и доступен во всех потоках DMA1 и DMA2. Адреса буферов задают регистры DMA_SxM0AR и DMA_SxM1AR, а текущий буфер показывает бит CT:

CTDMA работает сМожно менять
0M0ARM1AR
1M1ARM0AR

При включении DBM автоматически включается и кольцевой режим: после каждой передачи счётчик перезагружается, и поток продолжает работу уже со вторым буфером.

Смена буфера на лету

Главное отличие от простого кольцевого режима — адрес незанятого буфера можно изменить, пока поток работает. В остальных режимах RM0090 защищает регистры адреса памяти от записи, пока поток включён. Правила:

  1. Писать можно только адрес незанятого буфера. Запись в занятый устанавливает флаг ошибки TEIF и отключает поток.
  2. Удобный момент — прерывание по флагу TCIF: DMA только что переключился, и до следующего переключения есть время целой передачи.
  3. Если обработчик опоздал, возникает гонка: DMA уже переключился, и запись попадёт в занятый регистр.

Применения

  • Звук по I²S: пока один буфер выводится, следующий заполняет синтезатор или декодер.
  • Приём с АЦП крупными блоками, которые передают в очередь обработки и заменяют свободными буферами из пула.
  • Вывод кадров на дисплей.

Режим память — память с двойным буфером несовместим. У DMA STM32F1 (RM0008) двойного буфера нет — там используют кольцевой режим с обработкой половин. Для больших потоков его сочетают с пакетными передачами. Подробнее о семействе — STM32F4.

Частые вопросы

Чем двойной буфер лучше кольцевого режима с половинами?

Тем, что буферы независимы. В кольцевом режиме две половины — это один массив, и их адреса заданы раз и навсегда. В режиме двойного буфера адрес свободного буфера можно сменить на лету: например, отдать заполненный буфер в очередь на обработку и подставить новый из пула, не останавливая поток.

Как узнать, в какой буфер сейчас пишет DMA?

По биту CT в регистре DMA_SxCR. При CT = 0 DMA работает с адресом из DMA_SxM0AR, при CT = 1 — из DMA_SxM1AR. Менять разрешено только адрес незанятого буфера: при CT = 0 — M1AR, при CT = 1 — M0AR. Попытка записать адрес занятого буфера устанавливает флаг ошибки TEIF и отключает поток.

Когда безопаснее всего менять адрес буфера?

Сразу после флага завершения передачи TCIF. RM0090 советует именно это: в этот момент DMA только что переключился на другой буфер, и у программы есть целая передача, чтобы подставить новый адрес. Если опоздать, DMA переключится снова, и программа запишет адрес буфера, который уже занят.

Источники

  1. STMicroelectronics. RM0090 Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439, Rev 21 (June 2024) — разд. 10.3.9: режим двойного буфера доступен во всех потоках DMA1 и DMA2, включается битом DBM в DMA_SxCR; поток работает как обычный, но с двумя указателями памяти; при включении DBM кольцевой режим включается автоматически (бит CIRC не важен), в конце каждой передачи указатели меняются местами; программа обрабатывает одну область, пока DMA заполняет или читает другую; работает в обе стороны (память — источник или приёмник), табл. 46; адрес можно менять на лету: при CT = 0 можно писать DMA_SxM1AR, при CT = 1 — DMA_SxM0AR; запись в занятый регистр устанавливает флаг ошибки TEIF и отключает поток; адрес советуют менять сразу после флага TCIF; режим память — память с двойным буфером несовместим; в остальных режимах регистры адреса памяти защищены от записи, пока поток включён
  2. STMicroelectronics. RM0008 Reference manual: STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx, Rev 21 (February 2021) — разд. 13.2: возможности DMA STM32F1 — каналы, приоритеты, кольцевой буфер, флаги половины и конца передачи, память — память; режима двойного буфера с двумя адресами памяти в этом списке нет, его заменяют кольцевым режимом с обработкой половин по HTIF и TCIF

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