
Здесь мы продолжаем развитие платформы нашего ПЛК (PLC) под названием PLCS7 на базе модуля с микроконтроллером семейства Synergy S7FS2. В этом ПЛК ввод-вывод в основном выполняется через микросхемы расширители IO с последовательными каналами связи. Программный байтовый обмен с такими микросхемами может отбирать значительные ресурсы процессора. Но в микроконтроллерах Synergy есть модули DMA Controller (DMAC ) и Data Transfer Controller (DTC).
Разработка под семейство Sinergy поддерживается пакетом программного обеспечения SSP, в который входят, в частности, функции инициализации и запуска обмена по DMA и DTC. Несмотря на достаточно полную документацию понять как эффективно использовать движки DMA/DTC не так то просто, да ещё в комплекте с API SSP.

Отличия DTC от DMA в Synergy
DTC работает через ту же шину что и DMA, но DMA имеет приоритет над DTC. Запросы DMA всегда обслуживаются раньше чем запросы DTC. Обмен по DTC и DMA стартует по сигнальным событиям, а не по запросам DMA. Сигнальные события вызываются прерываниями периферии, но в отличие от прерываний сигнальные события не надо специально очищать чтобы они снова возникли. У DTC нет каналов, все запросы на обмен по DTC обслуживаются последовательно в порядке приоритетности сигналов прерываний вызвавших запрос DTC. DMA имеет 8 фиксированных каналов, где у канала 0 высший приоритет, а у канала 7 низший. Дескрипторы описывающие, как должна выполняться пересылка DTC хранятся в RAM и при каждом запуске DTC считываются из RAM и записываются вновь в RAM после модификации счетчика пересылок и адресов источника и приёмника данных. Дескрипторы для 8-ми каналов DMA хранятся в самом модуле DMA и при старте DMA не нужно читать их из памяти. DTC допускает чтение дескрипторов и выполнение пересылок по цепочке, размер цепочки не ограничен. DMA не обладает возможностью отработки дескрипторов по цепочке. В модуле DMA в каждом канале отрабатывается один дескриптор записанный в сам модуль DMA.
Таким образом DMA подходит для быстрых обменов блоками данных между памятью и единственным регистром периферии или между двумя областями памяти. А DTC годен для пересылок по самым разным адресам периферии за один проход без вмешательства процессора, но при этом нужно быть готовым к задержкам пересылок вследствие ожидания окончания всех пересылок DMA.
Влияние шинной архитектуры на DMA и DTC
При планировании DMA и DTC надо учитывать шинную архитектуру чипа. В нашем случае она такая:

Обычные скрипты линкера из демо-проектов объединяют пространство внутренней RAM от адреса 0x1FFE0000 до адреса 0x2007FFFF в один большой непрерывной блок памяти, в котором линкер может размещать что и как угодно.
На самом деле у RAM нижняя часть SRAMHS к DMA подключается через два моста, как видно из схемы. А верхняя половина RAM SRAM0, SRAM1 подключается к DMA через один мост. Т.е. для чтения из области SRAMHS модуль DMA будет тратить дополнительные циклы. Это отражено в документации. На доступ к SRAMHS модули DMA и DTC тратят дополнительно два цикла.
Это заставит нас пересмотреть все исходники и тщательно проверить где находятся области памяти к которым обращается DMA или DTC.
Важно помнить!
Нельзя допускать в линкере объединять области памяти SRAMHS и SRAM1 и 2, как это делается в простых демо проектах. Иначе переменные находящиеся на границе этих областей и пересекающие их будут вызывать сбой доступа или неверно читаться.
Нельзя размещать секцию линкера .hw_lock.* в области памяти SRAMHS. Это может привести к неработоспособности аппаратных блокировок используемых в драйверах SSP.
Области ниже и выше границы 0x20000000 имеют разные способы кэширования на уровне ядра ARM-Cortex M.
Область векторов DTC и управляющие пересылками DTC блоки (transfer information) должны располагаться в области SRAM0, SRAM1, чтобы не создавать дополнительных тактов при чтении-записи.
Планирование ресурсов DTC и DMA
Из сказанного выше становится понятно, что далеко не все пересылки в Synergy выгодно выполнять с помощью DMA, и не все пересылки стоит выполнять с помощью DTC.
Один из рисков - наткнуться на заторы, когда одна DMA пересылка будет мешать другой DTC пересылке или работа процессора может существенно замедляться. В этом случае следует подумать о реализации параллельной работы DMA, DTC и процессора.

Например, если процессор делает выборку команд из Flash и выборку операндов команд из HSRAM, то в это же самое время DTC без препятствий может пересылать данные из внешней SDRAM в периферию, например SPI. И в это же самое время DMA может пересылать данные из RAM1 в Ethernet. Т.е. могут существовать одновременно три потока данных не пересекаясь и не мешая друг другу.
В нашем PLC модуль Ethernet не используется, как и модуль графического вывода. Поэтому получится максимум два параллельных потока.
Ниже показано как были распланированы потоки DMA и DTC в нашем контроллере.

В первую очередь надо обратить внимание на обмен с микросхемами расширителями ввода-вывода аналоговых и цифровых сигналов. Он выполнен через DTC, поскольку требует цепочечных передач данных. Для расширителей ввода-вывода выбран интерфейс SPI. Если бы выбрали I2C, то не смогли бы работать без прерываний на каждой пакете. Работа с интерфейсом I2C в микроконтроллерах выполняется сложнее и медленнее чем с SPI с точки зрения ресурсов процессора.
Как выглядит управляющий блок DTC для цепочечной передачи было показано в этой статье
В нашем ПЛК установлен быстрый Wi-Fi модуль. Ему отдаём высший приоритет в каналах DMA. Блоки пересылки в Wi-Fi модуль имеют размер в 512 байт. Это занимает существенное время на шине данных микроконтроллера. Это приходится учитывать при работе с другой периферией не имеющей достаточного объёма собственных FIFO, чтобы переждать периоды занятости шины.
К сожалению у нас есть такая периферия с нетолерантностью к задержкам. Это линия адресных светодиодов B3DK3BRG-05C000113U1930. Протокол этих светодиодов повторяет протокол светодиодов WS2812B.

Если во время стрима на адресные светодиоды допустить задержку более нескольких микросекунд, то произойдёт плохо прогнозируемое искажение индикации на светодиодах. Однако задержку в микросекунду и меньше наши светодиоды успешно переносят. Поэтому для передачи информации на светодиоды применяется классический способ с таймером и ШИМ-ом, но при этом таймер имеет двойную буферизацию. В первичный буфер по DTC засылаются данные, а вторичный буфер генерирует паузу и грузится в первичный буфер если DTC не успевает записать данные из-за заторов на шине.

Резюме
Микроконтроллеры семейства Synergy показывают неплохую производительность при высокой загруженностью каналами прямой пересылки данных и имеют механизмы разделения потоков по отдельным шинам. В нашем ПЛК реализовано более 10 одновременно работающих каналов DMA и DTC. Однако корректная работа DMA не достаётся автоматически. Требуется тщательное планирование размещения в памяти и тестирование.