Открыть список
Как стать автором
Обновить

Как программировать многоядерные микроконтроллеры

Разработка робототехникиПрограммирование микроконтроллеровРазработка для интернета вещейПроизводство и разработка электроникиПроцессоры
Tutorial
Всего голосов 47: ↑47 и ↓0 +47
Просмотры11.5K
Комментарии 17

Комментарии 17

Спасибо за статью!
Похоже, как в RISC-V ядра работают.
В ARM мне казалось, что у всех надо на ассемблере ядра разделять в самом начале.

Все это должна делать операционная система, следующий шаг — за ней

В целом согласен.
Кстати, во FreeRTOS уже появляется соответствующий функционал и примеры его использования:
freertos.org/2020/02/simple-multicore-core-to-core-communication-using-freertos-message-buffers.html
freertos.org/STM32H7_Dual_Core_AMP_RTOS_demo.html
Достоинством микроконтроллеров является то, что они устроены относительно просто. Поэтому для стандартных задач можно использовать стандартные инструменты. Если же требуется что-то нестандартное или просто хочется поэкспериментировать и разобраться с тем, как всё устроено, часть вещей можно переписать самому.
Спасибо за наводку. Недавно как раз разорился на такую демонстрационную плату и хочется прикрутить к не RTOS средсвами CUBEIDE, чтобы несколько упростить себе жизнь по ручному созданию задач, очередей, семафоров…
На 407 давно освоил, а вот с двухъядерными много неожиданных проблем. Разбираюсь.
Спасибо. Хорошая и нужная статья. Все самое основное рассказано.
Я бы добавил только общие фразы. Например про то, что количество аппаратных семафоров конечно и необходимо адекватно оценивать потребности кода в них. И, если необходимо, строить собственные IPC на их основе.
Ну и пожелал не сталкиваться с задачами, требующими многоядерных контроллеров. А дабы и столкнулись, то рассмотреть вариант и CPU+MPU (big-LITTLE). Как правило такое проще поддерживать.
Ну и пожелал не сталкиваться с задачами, требующими многоядерных контроллеров

На деле, многоядерный МК — довольно классная штука. У меня сейчас в pet-проекте такой (LPC4300), руки никак не дойдут запустить.
Классная — потому что можно отдать всякую фигню типа моргания диодами и обмена по UART мелкому ядру, а основное — пусть молотит свою высокоуровневую логику, не отвлекаясь.
Да, идея выглядит крайне заманчиво — один камень пустить на обслуживание перефирии и первичную фильтрацию, второй уже на коммуникации с внешним миром и серьёзными расчётами…
По факту пока очень много заморочек с этим. В устройстве, которое сейчас готовлю в серию поставил на обработку внешних цифровых сигналов, в итоге дешувую STMку, для надёжности добавил гальваноразвязку. Получилось проще, надёжнее и пожалуй несколько подешевле чем H7 использовать в итоге. Но продолжаю осваивать H7 для проекта связанного с графикой, там в отличие от PLC место имеет значение да и задачи требуют серьёзной прозводительности

Спасибо за статью! Очень вовремя и полезно. Раньше в некоторых приложениях два микро приходилось ставить, теперь рассматриваем возможность один использовать с двумя ядрами.

А когда Вы два ставили, как реализовывали обмен данных между ядрами и обращение к общей периферии?

Общей периферии не было особо. Один использовался для расчетов и математики (например, фильтрация, расчеты скорости потока) второй просто для управления пользовательским интерфейсом. Данные по разному передавались, где по SPI, где по UART. Зависело от необходимой скорости и наличия нужных модулей на микроконтроллерах.

Спасибо за Ваш труд! Как раз над подобной моделью сейчас работаю.

Здравствуйте. А не подскажете, как можно сделать что-то типа load balancing cluster на двух МК или одноплатниках? Т.е. на обоих одинаковая ОС, если более слабому МК не хватает ресурсов для решения, он будит более мощный, но для пользователя это незаметно.

Если микроконтроллера всего два, то задача выглядит достаточно просто: на первом контроллере заводим прерывание по таймеру или высокоприоритетную задачу в RTOS, которая периодически просыпается и оценивает объём работы. Если оказывается, что ресурсов не хватает, то второму контроллеру отправляется сигнал на пробуждение (дёргается WAKE UP пин), а затем по какому-нибудь интерфейсу передаются задания для выполнения. Второй контроллер складывает полученные задачи в очередь. Если задачи в очереди заканчиваются, второй контроллер опять засыпает.


Но обычно load balancing cluster подразумевает использование большего числа устройств.


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


Если всё же такая задача возникала и решать её нужно на низком уровне, то здесь, думаю, можно выделить две схемы:


  • Все исполнители равноправны. Очередь задач хранится в общей памяти. В этом случае, скорее всего, возникнут проблемы с доступом к общей памяти и синхронизацией. Думаю, это либо будет медленно работать (подключение через SPI и I2C), либо будет сложно настроить (проброс шины во внешнюю SRAM через мультиплексор шины или использование многопортовой памяти).
  • Есть ведущий контроллер, который хранит у себя очередь задач и занимается их распределением между исполнителями. Здесь можно воспользоваться всем готовым. Распределение задач внутри ведущего контроллера можно организовать средствами любой нормальной RTOS (например, FreeRTOS). Далее запускаем эти задачи на исполнителях через какой-нибудь легковесный RPC или пишем свой под конкретную задачу и конкретный набор интерфейсов.

Если же у Вас одноплатные ПК с полноценным Linux и Ethernet, то там с большой вероятностью получится запустить какое-нибудь более или менее стандартное высокоуровневое решение: nginx, RabbitMQ, gRPC… Какое именно, зависит от конкретной задачи.


Опыта построения подобных систем у меня не было. Поэтому если кто-то сталкивался с реальными задачами из этой области, мне тоже было бы интересно узнать, как это было реализовано.

Хотелось бы в кои-то веки не паять, а взять два одноплатника (например, с А57 и А76) с линукс, соединить по ethernet/usb/pcie и попробовать сколхозить аналог bigLITTLE. Я пока не могу найти, как запускать условную читалку на «маленьком» одноплатнике, а для запуска браузера будить «большой» так, чтобы пользователю было незаметно.

Упрощённое решение: устанавливаем тяжеловесные приложения на отдельную машину и настраиваем запуск с пробросом графики через SSH или VNC. Если аккуратно написать скрипты и сделать для них соответствующие иконки, то пользователь может даже не догадываться, что некоторые программы запускаются на другом устройстве.


В качестве полноценного решения, кажется, Вам нужна распределённая операционная система: https://en.wikipedia.org/wiki/Distributed_operating_system

станавливаем тяжеловесные приложения на отдельную машину и настраиваем запуск с пробросом графики через SSH или VNC
Спасибо, так и поступлю. Почитал про распределенные ОС, слишком круто для меня, уж очень далеко от «Далее-далее-готово», хотя скорее всего это более правильный подход.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.