Комментарии 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
Достоинством микроконтроллеров является то, что они устроены относительно просто. Поэтому для стандартных задач можно использовать стандартные инструменты. Если же требуется что-то нестандартное или просто хочется поэкспериментировать и разобраться с тем, как всё устроено, часть вещей можно переписать самому.
Логично
На 407 давно освоил, а вот с двухъядерными много неожиданных проблем. Разбираюсь.
Я бы добавил только общие фразы. Например про то, что количество аппаратных семафоров конечно и необходимо адекватно оценивать потребности кода в них. И, если необходимо, строить собственные IPC на их основе.
Ну и пожелал не сталкиваться с задачами, требующими многоядерных контроллеров. А дабы и столкнулись, то рассмотреть вариант и CPU+MPU (big-LITTLE). Как правило такое проще поддерживать.
Ну и пожелал не сталкиваться с задачами, требующими многоядерных контроллеров
На деле, многоядерный МК — довольно классная штука. У меня сейчас в pet-проекте такой (LPC4300), руки никак не дойдут запустить.
Классная — потому что можно отдать всякую фигню типа моргания диодами и обмена по UART мелкому ядру, а основное — пусть молотит свою высокоуровневую логику, не отвлекаясь.
По факту пока очень много заморочек с этим. В устройстве, которое сейчас готовлю в серию поставил на обработку внешних цифровых сигналов, в итоге дешувую STMку, для надёжности добавил гальваноразвязку. Получилось проще, надёжнее и пожалуй несколько подешевле чем H7 использовать в итоге. Но продолжаю осваивать H7 для проекта связанного с графикой, там в отличие от PLC место имеет значение да и задачи требуют серьёзной прозводительности
Спасибо за статью! Очень вовремя и полезно. Раньше в некоторых приложениях два микро приходилось ставить, теперь рассматриваем возможность один использовать с двумя ядрами.
Общей периферии не было особо. Один использовался для расчетов и математики (например, фильтрация, расчеты скорости потока) второй просто для управления пользовательским интерфейсом. Данные по разному передавались, где по SPI, где по UART. Зависело от необходимой скорости и наличия нужных модулей на микроконтроллерах.
Спасибо за Ваш труд! Как раз над подобной моделью сейчас работаю.
Если микроконтроллера всего два, то задача выглядит достаточно просто: на первом контроллере заводим прерывание по таймеру или высокоприоритетную задачу в RTOS, которая периодически просыпается и оценивает объём работы. Если оказывается, что ресурсов не хватает, то второму контроллеру отправляется сигнал на пробуждение (дёргается WAKE UP пин), а затем по какому-нибудь интерфейсу передаются задания для выполнения. Второй контроллер складывает полученные задачи в очередь. Если задачи в очереди заканчиваются, второй контроллер опять засыпает.
Но обычно load balancing cluster подразумевает использование большего числа устройств.
Для чисто вычислительных задач микроконтроллеры используют редко. Обычно используется много периферии, которая требует физического подключения к различным устройствам. Поэтому систем, в которых можно динамически раскидывать задачи между контроллерами, мало. Готовых решений для таких задач на низком уровне я не знаю.
Если всё же такая задача возникала и решать её нужно на низком уровне, то здесь, думаю, можно выделить две схемы:
- Все исполнители равноправны. Очередь задач хранится в общей памяти. В этом случае, скорее всего, возникнут проблемы с доступом к общей памяти и синхронизацией. Думаю, это либо будет медленно работать (подключение через SPI и I2C), либо будет сложно настроить (проброс шины во внешнюю SRAM через мультиплексор шины или использование многопортовой памяти).
- Есть ведущий контроллер, который хранит у себя очередь задач и занимается их распределением между исполнителями. Здесь можно воспользоваться всем готовым. Распределение задач внутри ведущего контроллера можно организовать средствами любой нормальной RTOS (например, FreeRTOS). Далее запускаем эти задачи на исполнителях через какой-нибудь легковесный RPC или пишем свой под конкретную задачу и конкретный набор интерфейсов.
Если же у Вас одноплатные ПК с полноценным Linux и Ethernet, то там с большой вероятностью получится запустить какое-нибудь более или менее стандартное высокоуровневое решение: nginx, RabbitMQ, gRPC… Какое именно, зависит от конкретной задачи.
Опыта построения подобных систем у меня не было. Поэтому если кто-то сталкивался с реальными задачами из этой области, мне тоже было бы интересно узнать, как это было реализовано.
Упрощённое решение: устанавливаем тяжеловесные приложения на отдельную машину и настраиваем запуск с пробросом графики через SSH или VNC. Если аккуратно написать скрипты и сделать для них соответствующие иконки, то пользователь может даже не догадываться, что некоторые программы запускаются на другом устройстве.
В качестве полноценного решения, кажется, Вам нужна распределённая операционная система: https://en.wikipedia.org/wiki/Distributed_operating_system
Как программировать многоядерные микроконтроллеры