Pull to refresh

Comments 22

а зачем использовать Raspberry?
это как микроскоп вместо молотка
возьмите например STM32F030 за 1$
и играйтесь с DMA
С помощью DMA управлять шаговыми двигателями микроконтролерами типа stm32 не получится (или это будет притянуто за уши) из-за банальной нехватки оперативной памяти для буфера. А вот просто использовать stm32 без операционной системы/с операционной реального времени можно. Существует множество реализаций, автор статьи так же является автором одной из них.
Для каких-то целей этого вполне достаточно. Но всегда хочется иметь что-то более современное, например, просто подключить полноценный монитор или иметь Wi-Fi на самом блоке управления. Да, безусловно, все это можно реализовать и на маленьком микроконтроллере, но это будет несравнимо сложнее, чем просто вставить usb-донгл в плату (в случае RPi3 он уже сразу есть на плате).
Кроме того, разработка под микроконтроллер, как правило, ведется на Си/Си++, что заметно сложнее, чем писать на Python. Можно долго филосовствовать о плюсах языков высокого уровня, но в любом случае Python обеспечит более простую портируемость одного и того же кода между процессорами/платами/платформами. В случае того же контроллера CNC достаточно лишь реализовать доступ к DMA, и остальная часть, скорее всего, заработает сразу.
Так же не забываем о вопросе производительности. Тот же слайсер для 3d-принтера можно запускать сразу на Raspberry Pi, для микроконтроллера он будет тяжеловат по занимаемому в прошивке месту и производительности.
И опять же производительности микроконтроллера наверняка не хватит, чтобы считать в реальном времени с десяток осей какого-нибудь более сложного устройства. Для Raspberry Pi это не будет большой задачей в принципе, т. к. в случае того же DMA у Raspberry Pi можно управлять выводами платы количеством до 64, т. е. это до 64 шаговых двигателей (за вычетом используемых внутри самой платы и небольшого числа пинов для выбора направления вращения). Есть ARM-процессоры и с большим количеством выводов.
А по поводу стоимости, в статье уже отмечалось, что Raspberri Pi Zero стоит $5 — и это целая плата. Плата с микроконтроллером будет стоить больше $1, и конечная разница все равно окажется смешной.
Наивное заблуждение считать DMA этаким детерминированным автоматом не потребляющим ресурсы.
DMA делит ту же шину AHB что и процессор и они между прочим могут там конфликтовать.
DMA замедляет работу процессора. А еще каналы DMA конфликтуют друг с другом.
Поскольку Raspberry Pi не проектировался для систем реального времени у меня большие сомнения что его DMA работает достаточно детерминированно и без сбоев при большом количестве каналов.
В любом случае даже DMA требует рано или поздно прерываний и тут детерминизму в Raspberry Pi придет конец.
Ну и наконец писать такие программы на Python это очень странно. В Pythone нет никаких средств наблюдения за регистрами процессора и периферии в реальном времени. Невозможно увидеть никаких внутренних переменных драйверов, нельзя оперативно менять содержимое регистров и т.д. и т.п. Это язык абсолютно оторванный от реального времени.
Для управления моторами есть прекрасные микроконтроллеры STM32, Kinetis и т.д.
Специально заточены, гораздо более гибкий и контролируемый DMA чем у Raspberry Pi, полная доступность всех регистров периферии и процессора в реальном времени, даже трассировка прерываний и исполнения кода. Жесткая детерминированность.

Ресурсы конечны всегда, и производительность ARM-процессора на порядок выше, чем у какого-нибудь STM32. Именно потому, что DMA-каналы могут влиять друг на друга, в статье и предлагается синхронизироваться еще с PWM-модулем на процессоре, а не копировать в лоб.
Если не нравится Python, можно реализовать то же самое хоть на Go, хоть на Java, хоть на чем угодно другом. Вся суть алгоритма сводится как раз к тому, чтобы избежать работы в реальном времени на уровне приложения и передать ее другим аппаратным модулям — пускай они с регистрами и работают.
Программы тоже можно писать на ассемблере, но зачем, когда есть более удобные инструменты.
Наверно будет кому-то откровением, но частота APB шины у PI всего 350 МГц.
Это та шина через которую работает DMA.
А у STM32H7 есть четыре! шины AHB по 200 МГц. Чувствуете разницу?
Это значит что STM32 существенно быстрее работает с периферией чем PI.
Если учесть что STM32 работает не с DDR а с более детерминированной SRAM, то и вовсе по быстродействию при работе с большим количеством двигателей STM32 уделает PI.
Жаль, только в 1 МБ оперативной памяти STM32H7 создать буфер для длительной работы DMA не получится. Да в принципе DMA здесь будет оверкиллом, эффективнее в рилтайме считать и дергать выводы напрямую из регистров.
Но в любом случае я сомневаюсь, что вы сильно забьете шины этими активностями. Гораздо раньше вы упретесь в производительность вычисления какого-нибудь синуса или косинуса при реализации круговой интерполяции… Даже 4х ядер Raspberry Pi при вычислении тригонометрии заданного движения вряд ли хватит чтобы существенно занять полосу DMA.
Заканчиваю уже занудствовать. Только напоследок скажу что оперативная память для DMA тоже за уши притянута.
При импульсе в 1 мкс можно данные и из SPI Flash читать или NAND. А уж это то подключаются к любым микроконтроллерам и размеры может иметь какие угодно.
Хотя сама идея заранее формировать импульсы для управления двигателем на интервале минуты без корректировки по обратной связи вызывает нехорошие чувства.
Даже 4х ядер Raspberry Pi при вычислении тригонометрии заданного движения вряд ли хватит чтобы существенно...
Есть элементарные быстрые алгоритмы интерполяции без FPU — точность движков ведь там не супер…

А на STM32 делают пром.контроллеры с управлением движением по паре осей. Кажется Delta и Овены.

Но всегда хочется иметь что-то более современное, например, просто подключить полноценный монитор или иметь Wi-Fi на самом блоке управления.
А по поводу стоимости, в статье уже отмечалось, что Raspberri Pi Zero стоит $5 — и это целая плата.
Противоречие, на Pi0 нет вифи.

И с учетом жестких накладок по пинам на Пи- кажется, что они все же для других задач планировались. Хотя сама идея DMA очень привлекательна

На P0W (Raspberry Pi Zero W) — есть.

А чем критична постоянная скорость для CNC? В том плане зачем требуется именно постоянная скорость? Ведь мы управляем подачей инструмента а не скоростью вращения. Это же не 3д принтер где простой, с постоянной подачей пластика, может повлиять на геометрию фигуры.

P.S. что случилось со статьей? Куда делись предыдущие комментарии?
При скачке скорости у CNC, например с фрезой, фрезу может переломить, если она не сумеет пропилить материал. Да и сам пропил будет плохого качества, если она будет все время дергаться.
Говоря про постоянную скорость, мы скорее имели в виду изменения скорости в более узком временном интервале. А именно, если импульсы на шаговый двигатель буду идти с неправильными (в случае линейного движения с разными) интервалами, мотор будет резко дергаться (ведь фактически мы будем изменять скорость, что моментально нельзя сделать чисто физически), а это будет давать сильные нагрузки на механику устройства.
P.S. Извините, произошла накладка, открыли повторно, действительно потеряли два комментария. Просим прощения у их атворов!
если это не было не преднамереное удаление, то снова задам свой первый вопрос:
каждый импульс будет занимать 128 байт (четыре контрольных блока по 32 байт)

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

P. S. Спасибо за вопрос, удаление, разумеется, не было преднамеренным!
Спасибо за ответ. Но остается не понятным каким образом задается «задержка».
Правильно понимаю, что для PWM модуля выделяется еще один канал DMA и там как раз эти блоки и используются?
DMA все тем же одним каналом (внутри контрольных блоков адрес назначения меняется на адрес PWM-модуля) пишет в FIFO буфер модуля PWM. Дело в том, что PWM-модуль сериализует свой FIFO-буфер с жесткой ограниченной частотой, и DMA-модуль при копировании данных вынужден ждать сигнала готовности принятия данных в буфер. Получается, что мы можем реализовать довольно точную задержку за счет того, что запись N байт в PWM займет известное (согласно частоте PWM-модуля) время.
Здорово! Особенно заинтересовал сам ключевой момент — использование устройства как микро-компьютера с полным фаршем на борту и при том работа на самом низком низком уровне, необходимом для управления приводами и прочим электрическим добром. Т.е. доступ по локалке для обмена информацией стандартными средствами, без плясок с бубном. Нормальный Линукс, стандартные сервисы + управление сторонним железом и все одной платой.

Как на ваш взгляд, какое ограничение (программное + аппаратное) имеет ваш подход к реализации, скажем большого количества каналов ШИМов и АЦП, скажем для управления N устройствами с парой ШИМ и тройкой АЦП на устройство?
Проект также использует DMA-модуль, авторы говорят о возможности генерировать несущую до 250 МГц. Очевидно, что DMA-модуль простым копированием буфера не сможет передать сигнал с частотной модуляцией на такой частоте. Реализация хитра и красива.

Задумка ужасна до слез. 21 век на дворе, радиоресурсы это ценность почище воздуха, а такие методы его нерационального использования вызывают желание оторвать руки реализаторам.
Сама статья очень крута, спасибо за нее.
P.S. Ответил не там.
Подводные камни- Много каналов==много выделяемой памяти
Сложные сигналы== много выделяемой памяти
Небольшой джиттер по фазе
Большой или не большой зависит от драйверов остального «фарша».
Самый большой поток DMA идет на дисплей, потом потоки DMA на несколько USB, потом DMA на SD карту, Если Ethernet есть, то DMA же нужен и для него…
А если еще кто нибудь задумает камеру подключить, то не удивлюсь если DMA на GPIO будет выдавать ошибку.
Автор скорее всего на свой Raspberry Pi даже не дышит чтобы он протянул минуту работы DMA без искажения сигналов.
Об АЦП
АЦП на борту у Raspberry Pi нету. Можно по I2C подключить внешний ADC, например ads1115 — потенциально 4 канала ADC и 255 устройств на шине. Можно подумать над подключением других внешних ADC и получить еще больше каналов. Так что ограничения возникнут скорее от того, что вы собираетесь делать с данными от этих устройств, чем от количества самих девайсов.

О ШИМ
ШИМ можно реализовать этим методом, ограничением в данном случае будут именно количество ножек процессора и максимальная частота ШИМа. В случае Raspberry Pi, у процессора есть 64 вывода, из которых следует вычесть используемые на самой плате. В реальности на разъем платы выведено 26 выводов, которые доступны для ШИМа таким методом. Хотя потенциально можно было бы использовать все 64 вывода, будь они выведены на разъем и не подключены к чему-нибудь внутри.

В вашем примере, если предположить, что два вывода мы отдадим на подключение ADC, получим 12 устройств.
Большое спасибо за ответ!
На самом деле в упомянутой задаче про N устройств в расчете на одно устройство одновременно (условно, конечно) нужен 1 ШИМ (управление силовым ключем) и 2 АЦП (ток и напряжение), еще 1 I2C (температура) или один 1-Wire (тут частота опроса не критична). Другое дело, что второй набор пинов на то же самое устройство не должен совпадать с первым, за исключением измерителей температуры.

На самом деле не хочется огород колхозить из кучи промежуточных плат.
А нельзя было запинить память в RAM через mlock(2)?

> mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM, preventing that memory from being paged to the swap area.
mlock() блокирует лишь виртуальную память, т. е. он предотвратит попадание памяти в swap. Но реальный адрес в физической памяти все равно может быть изменен, т. к. память может быть перенесена по желанию менеджера памяти (например, чтобы дефрагментировать память).
В документации ядра сказано: Linux supports migration of mlocked pages and other unevictable pages. This involves simply moving the PG_mlocked and PG_unevictable states from the old page to the new page.
Sign up to leave a comment.