Я рекомендую читать исходный код RPIO вместе с ServoBlaster, поскольку он немного упрощен и может помочь в понимании. Также очень важно: руководство Broadcom BCM2835, содержащее все мелкие детали.
есть схема блоков?
Руководство содержит все функции, предлагаемые чипом (хотя, насколько я видел, не в виде блок-схемы).
Верно ли следующее понимание:
Контроллер DMA является частью основного чипа (Broadcom, хотя я думаю, что то же самое происходит и в настольных процессорах). Он не может точно запускать код, но может самостоятельно копировать память между периферийными устройствами, не потребляя время основного процессора. Контроллер прямого доступа к памяти имеет разные каналы, которые могут независимо копировать память и работать независимо от процессора.
Его можно настроить с помощью "блоков управления" ( Руководство BCM, стр. 40, 4.2.1.1): вы можете указать контроллеру DMA сначала скопировать память из A в B, затем из C в D и так далее.
не понимаю, как именно DMA и PWM работают вместе
DMA используется для отправки данных в PWM («Широко-импульсный модулятор», руководство BCM, стр. 138, глава 9), который потребляет данные и создает очень точную задержку. Интересно, что ШИМ-контроллер... используется не для генерации ШИМ-импульсов, а просто для ожидания.
Может кто-нибудь объяснить, как это работает?
В конечном счете, вы настраиваете значение контактов GPIO (или настройки генератора PWM или PCM) с помощью установка памяти по специальному адресу; память в этой области представляет периферийный configuration (руководство BCM, стр. 89, глава 6) .
Итак, идея такова: копировать 1 в память, которая управляет значением контакта GPIO, используя контроллер DMA; дождитесь ширины импульса; скопируйте 0 в значение вывода GPIO; подождите оставшуюся часть периода; петля. Поскольку это делает контроллер прямого доступа к памяти, он не потребляет циклы процессора.
Ключевым моментом здесь является возможность заставить DMA-контроллер «ждать» точное количество времени, и для этого RPIO и ServoBlaster используют ШИМ-контроллер в режиме FIFO (подобный функционал есть и у генератора PCM, но давайте придерживаться ШИМ) . Это означает, что ШИМ-контроллер будет «отправлять» считанные им данные из своей так называемой очереди FIFO, а затем останавливаться. Неважно, как оно «отправлено» (руководство BCM, стр. 139, 9.4 MSENi=0
), ключевым моментом является то, что оно требует фиксированного количества времени. На самом деле, даже не важно, какой данные отправляются: контроллер DMA настроен на запись в очередь FIFO, а затем ждет, пока контроллер PWM закончит отправку данных, и это создает очень точную задержку.
Разрешение результирующего импульса определяется длительностью передачи ШИМ, которая зависит от частоты, на которой работает ШИМ-контроллер.
Пример
У нас есть максимальное разрешение 1 мс (задается задержкой ШИМ), и мы хотим иметь импульс с рабочим циклом 25% с частотой 125 Гц. Таким образом, период импульса составляет 8 мс. Выполненная операция DMA будет
- Установите вывод на 1 (DMA записывает в память GPIO)
- Подождите 1 мс (DMA записывает в PWM FIFO)
- Подождите 1 мс (DMA записывает в PWM FIFO)
- Установите вывод на 0 (DMA записывает в память GPIO)
- Подождите 1 мс (DMA записывает в PWM FIFO)
- ...повторите "Подождите 1 мс" еще 4 раза.
- Подождите 1 мс (DMA записывает в PWM FIFO) и вернитесь к 1.
Таким образом, потребуется как минимум 10 блоков управления DMA (8 инструкций ожидания, заданных периодом/задержкой, плюс 2 операции записи).
Примечание: в ServoBlaster и RPIO он потребляет ровно 16 блоков управления DMA, потому что (для большей точности) они всегда выполняют операцию "копирования памяти" перед "операцией ожидания". Операция «копирования памяти» — это всего лишь фиктивная операция, если только ей не нужно изменить значение вывода.
person
Pietro Saccardi
schedule
28.10.2018