Урок 33. Прямой доступ к памяти в STM32. Контроллер DMA.

Контроллер ПДП

В уроке узнаем о способе передачи данных в режиме прямого доступа к памяти, реализации этого процесса в микроконтроллере STM32. Подробно изучим режимы работы, форматы регистров, особенности контроллера ПДП STM32.

Предыдущий урок     Список уроков     Следующий урок

Микроконтроллер обменивается данными с “внешним миром” только через периферийные устройства, а данные хранит в памяти. Поэтому в любой реальной программе существует задача обмена данными между оперативной памятью микроконтроллера и периферийными устройствами. Также бывает необходимость в  обмене данными между блоками памяти (копирование блоков) и в передаче информации с одного периферийного устройства на другое.

 

В предыдущих уроках мы реализовывали подобные задачи программным способом. В цикле считывали данное из памяти или регистра и загружали его в регистр или память.

  • В каких-то случаях управление периферийными устройствами с помощью программных операторов выглядело единственным логичным вариантом. Например, когда мы зажигали светодиод, подключенный к порту ввода/вывода. Странно было бы установить ячейку памяти в нужное состояние, а затем с помощью дополнительных аппаратных узлов переслать ее содержимое на порт ввода/вывода.
  • В других случаях передача данных из программы нас вполне устраивала, не вызывала проблем в реализации. Например, когда выводили сообщения из массива или текстовой строки в последовательный порт. Но уже тогда было заметно, что мощный процессор использует минимум своих вычислительных возможностей. Он просто ждет освобождения контроллера UART, считывает данное из памяти и записывает его в регистр данных контроллера UART. И так нужное количество циклов.

Использование прерываний позволяло только оперативно перераспределять работу процессора между задачами. Процессор все равно занимался примитивными операциями – пересылкой данных.  Программа была простой, и мы могли позволить тратить почти все процессорное время на копирование данных.

  • А вот при реализации цифрового осциллографа в уроке 29 программное чтение данных АЦП значительно ограничивало возможности устройства. На время чтения развертки осциллографа программа работала в блокирующем режиме, зависала. Приходилось даже запрещать прерывания. Благодаря высокому быстродействию STM32 удалось считывать данные АЦП с дискретностью 1 мкс, но это был предел. С большей скоростью поток данных уже не обработать.

А ведь задача пересылки данных между памятью и периферийным устройством с аппаратной точки зрения очень простая. Достаточно аппаратного счетчика адреса памяти, счетчика количества данных и промежуточного регистра. Данное считывается, например, из АЦП и записывается в память по адресу из специального регистра-счетчика. Его содержимое увеличивается на 1, и новое данное из АЦП записывается в память по следующему адресу. Процесс продолжается пока счетчик количества данных не остановит работу устройства. При этом процессор продолжает выполнение основной программы.

Подобные аппаратные узлы содержатся во всех современных высокопроизводительных микроконтроллерах. Конечно, их устройство сложнее, чем я описал в предыдущем абзаце, но и функций намного больше.

Процесс обмена данными без участия процессора (за счет аппаратных узлов микроконтроллера)

  • между памятью и периферийными устройствами микроконтроллера,
  • или между периферийными устройствами,
  • или между блоками памяти

называется прямым доступом к памяти (ПДП). Английская аббревиатура DMA - Direct memory access.

Аппаратная часть микроконтроллера, реализующая процесс прямого доступа к памяти называется контроллер прямого доступа к памяти (контроллер DMA).

Использование ПДП (DMA) позволяет:

  • освободить процессор для выполнения других задач;
  • обеспечить высокие скорости передачи данных, недостижимые при использовании программного способа обмена.

Контроллер ПДП

Устройство контроллеров DMA, как правило, простое, очевидное и понятное для разработчиков программ.

 

Общие принципы работы контроллера прямого доступа к памяти в STM32.

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

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

  • В микроконтроллере STM32F103c8 есть только один контроллер DMA c 7 каналами. В микроконтроллерах старших серий (high-density и XL-density) добавлено второе устройство DMA.
  • Как я писал выше, прямой доступ к памяти происходит по общей с процессором системной шине. Поэтому при одновременном обращении к памяти или периферийному устройству процессора и контроллера DMA могут возникать конфликты. В результате работа процессора может приостанавливаться, но как минимум половина пропускной способности системной шины отдается процессору. Программа будет выполняться даже при интенсивном обмене через прямой доступ к памяти. Не говоря о том, что не каждая команда программы работает с оперативной памятью или периферийным устройством.
  • Инициаторами обмена с помощью контроллера DMA являются аппаратные события микроконтроллера (event). Конечно, при наличии соответствующих разрешений в управляющих регистрах. В уроке 18 я писал о событиях, и чем они отличаются от прерываний.

В общем случае прямой доступ к памяти происходит следующим образом.

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

Сам обмен данными (транзакция) с использованием DMA состоит из трех операций.

  • Данное загружается в промежуточный регистр из памяти или из регистра данных периферийного устройства в зависимости от направления обмена. Адреса памяти и периферийного устройства содержатся в специальных регистрах.
  • Данное перегружается в память или регистр данных периферийного устройства.
  • Регистр количества транзакций (элементов обмена) уменьшается на 1. При достижении 0, обмен завершается.

Все просто и логично.

Каналы DMA.

Повторюсь. В микроконтроллере STM32F103c8 есть только один контроллер DMA c 7 каналами.

С точки зрения программиста каждый канал – это отдельный аппаратный узел микроконтроллера. Он осуществляет DMAпередачу между регистром данных периферийного устройства (расположенным по фиксированному адресу) и памятью.

Каналы работают с общей памятью, через общую шину данных. Поэтому между ними могут возникать конфликты, которые разрешаются следующим способом.

В каждый момент времени обмен данными может происходить только по одному каналу. При нескольких активных каналах контроллер DMAразрешает работу канала с более высоким приоритетом.

Приоритет каждого канала устанавливается программно и может иметь четыре уровня:

  • Very high priority (очень высокий);
  • High priority (высокий);
  • Medium priority (средний);
  • Low priority (низкий).

При активных каналах с одинаковым уровнем приоритета преимущество имеют каналы с меньшим номером.

 

Регистры каналов.

Каждый канал для нас – отдельный аппаратный контроллер передачи данных.

Каждый канал имеет 4 собственных регистров, которые полностью определяют режим обмена данными по нему.

Каналы настолько независимы, что если вести речь обо всех регистрах контроллера DMA, то к регистрам каналов добавятся только регистры управления прерываниями.

Итак 4 регистра, с очевидным назначением.

  • DMA_CMARx — адрес памяти, по которому выполняется запись или чтение в зависимости от направления передачи данных.
  • DMA_CPARx — адрес регистра данных периферийного устройства, из которого выполняется чтение или в который производится запись. В режиме обмена данными между блоками памяти он также содержит адрес памяти.
  • DMA_CNDTRx — содержит  количество элементов для передачи (количество транзакций).  В качестве элемента транзакции могут быть выбраны байт, полуслово, слово.
  • DMA_CCRx — регистр конфигурации канала. Разрешает работу канала, определяет режимы передачи данных.

Полное описание регистров есть в справочнике.

Количество элементов данных для передачи устанавливается программно и может быть от 0 до 65535.

В общем случае обмен DMA происходит между памятью и периферийным устройством. Источником или приемником данных периферийного устройства является регистр данных этого устройства. Он имеет фиксированный адрес, который должен оставаться неизменным в ходе DMA обмена.

Что касается памяти, то как правило, необходимо записывать или считывать данные по последовательно расположенным адресам.

Для этого существует режим инкрементации адреса. Он доступен как для адреса памяти (бит MINC регистра DMA_CCRx), так и для адреса периферийного устройства (бит PINC регистра DMA_CCRx). Хотя в последнем случае не имеет смысла.

Таким образом, после каждого обращения к памяти указатель увеличивается на 1, 2 или 4, в зависимости от заданного размера элемента данных. Начальные адреса передачи данных хранятся в регистрах DMA_CMARx (для памяти) и DMA_CPARx (для периферии). В процессе обмена данными их значения не изменяются, а текущие значения указателей содержатся во внутренних регистрах микроконтроллера и программе недоступны.

Размер элементов данных транзакции может иметь значения:

  • 8 бит (байт);
  • 16 бит (полуслово);
  • 32 бита (слово).

Выбор размера данных осуществляется независимо не только для каждого канала, но и отдельно для приемника и передатчика данных каждого канала. Для этого в регистре DMA_CCRx  существуют битовые поля PSIZE и MSIZE.

После выполнения последней передачи запросы по каналу перестают обслуживаться. Регистр количества данных передачи DMA_CNDTRx содержит 0. Чтобы инициировать новый DMA обмен необходимо загрузить в него новое значение. Это возможно только после отключения канала. При этом все остальные регистры канала (DMA_CMARx, DMA_CPARx и DMA_CCRx) сохраняют значения.

Если задан циклический режим (бит CIRC регистра DMA_CCRx), то по окончанию передачи данных в регистр DMA_CNDTRx автоматически загружается его первоначальное значение и процесс DMA обмена возобновляется.

 

Конфигурация канала DMA.

Для использования канала необходимо конфигурировать его, выполнив следующую последовательность действий. Изначально канал должен быть запрещен (бит EN регистра DMA_CCRx сброшен).

  • Загрузить в DMA_CPARx адрес регистра данных периферийного устройства. Данные будут записываться/считываться по этому адресу после возникновения события периферийного устройства, формирующего запрос DMA.
  • Загрузить в DMA_CMARx начальный адрес блока памяти. В этот блок будут записываться данные из периферийного устройства, либо из него будут считываться данные для передачи в периферийное устройство.
  • Записать в DMA_CNDTRx общее количество элементов обмена. Каждая транзакция будет уменьшать значение этого регистра. При достижении 0, DMA передача будет остановлена.
  • Задать конфигурацию DMA передачи в регистре DMA_CCRx: направление передачи, приоритет канала, режим инкрементирования, размер элемента данных и т.д.
  • Включить канал битом EN регистра DMA_CCRx.

После этого начинают обрабатываться запросы от периферийных устройств, подключенных к каналу.

Чтением регистра DMA_CNDTRx можно узнать количество оставшихся для передачи элементов.

  • После завершения передачи половины от общего количества элементов, будет установлен флаг HTIFx в регистре DMA_ISR. Произойдет прерывание на это событие, если оно разрешено в регистре DMA_CCRx (бит HTIE).
  • После завершения передачи всех данных, будет установлен флаг TCIFx в регистре DMA_ISR. Произойдет прерывание на это событие, если оно разрешено в регистре DMA_CCRx (бит TCIE).
  • Если не задан циклический режим, то после пересылки заданного количества данных работа канала останавливается.
  • В циклическом режиме (бит CIRC регистра DMA_CCRx) после завершения передачи данных, в регистр DMA_CNDTRx автоматически перезагружается его первоначальное значение, и обмен продолжается бесконечно.

 

Режим “из памяти в память”.

Режим используется для копирования блоков данных в памяти.

  • Для его конфигурации необходимо установить бит MEM2MEM в регистре DMA_CCRx.
  • После включения канала битом EN регистра DMA_CCRx сразу начнется передача данных. Дополнительные запросы не требуются.

Режим запрещено использовать совместно с циклическим режимом.

 

Выравнивание данных разной разрядности.

При DMA передаче данных разрядности приемника и источника могут не совпадать.  Действует простое и логичное правило. Всегда сохраняются младшие разряды.

  • Если разрядность источника превышает разрядность приемника, то лишние старшие разряды источника игнорируются. Например, 32х разрядное число 0x87654321 передаем в периферию с регистром данных 16 разрядов. В него запишется 0x4321.
  • Если разрядность источника меньше разрядности приемника, то недостающие старшие разряды в приемнике будут заполнены нулями. Например, 16ти разрядное число 0x4321 источника загружаем в 32х разрядный приемник. Запишется 0x00004321.

В принципе используется правило преобразования (приведения) типов данных языка C.

 

Специфика доступа к периферийным устройствам через шины AHB/APB.

Периферийные устройства STM32 подключены к процессору и памяти через шины AHB/APB. Это 32х разрядные шины. Они не поддерживают операций передачи меньшей разрядности. В результате в регистры периферийных устройств можно записывать или считывать из них только 32х разрядные слова.

Многие регистры периферии имеют меньшую разрядность, часто 16 разрядов. В оставшиеся биты при передаче данных DMA тоже что-то будет записываться. В большинстве случае это не важно, разряды не значащие. Но все-таки давайте внесем определенность в этот процесс.

При записи в периферийное устройство байта или полуслова через шину AHB данные на неиспользуемых линиях шины дублируются. Например.

  • Если мы записываем полуслово 0x4321, в регистр периферии загрузится 0x43214321.
  • Если мы записываем байт 0x21, в регистр периферии загрузится 0x21212121.
  • Но если мы укажем разрядность источника слово, т.е. запишем слово 0x87654321, а разрядность периферийного регистра укажем полуслово, то произойдет выравнивание разрядности, описанное в предыдущем абзаце. В результате в регистр загрузится 0x00004321.

 

Ошибки при DMA передаче.

Ошибка может возникнуть только в результате попытки доступа к зарезервированному адресному пространству. В этом случае канал, в котором произошла ошибка, отключается аппаратным сбросом бита EN. Устанавливается флаг ошибки TEIFx в регистре DMA_ISR. И формируется прерывание, если оно разрешено битом TEIE в регистре DMA_CCRx.

 

Прерывания DMA.

Для каждого канала могут генерироваться прерывания по следующим флагам регистра DMA_ISR.

  • HTIFx – завершена передача половины данных. Разрешается прерывание битом HTIE в регистре DMA_CCRx.
  • TCIFx - завершена передача всех данных. Разрешается прерывание битом TCIE в регистре DMA_CCRx.
  • TEIFx – ошибка передачи. Разрешается прерывание битом TEIE в регистре DMA_CCRx.

 

Соответствие каналов DMA периферийным устройствам.

Каналов DMA только 7. Периферийных устройств больше. Поэтому на каждый канал поступают сигналы запросов от нескольких периферийных устройств, объединенные логическим элементом ИЛИ. В каждый момент времени только одно устройство может использовать канал.

Остальные периферийные устройства должны отключить свои запросы DMA. Для этого у каждого устройства с поддержкой DMA есть специальный бит активации/деактивации формирования запроса.

Остается привести таблицу соответствия каналов DMA периферийным устройствам.

Соответствие каналов DMA периферийным устройствам STM32

На мой взгляд, контроллер DMA один из самых простых и понятных узлов STM32.

 

В следующем уроке будем разрабатывать программы, использующие контроллер DMA.

 

Предыдущий урок     Список уроков     Следующий урок

0

Автор публикации

не в сети 8 часов

Эдуард

280
Комментарии: 1936Публикации: 197Регистрация: 13-12-2015

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".