Обновить
35
0
Никита@mingl

Пользователь

Отправить сообщение

1. Аппаратно с помощью прерываний вотчдога

Во многих микроконтроллерах сторожевые таймеры (watchdog) помимо полноценной перезагрузки могут отправлять запросы на прерывания. Есть предупреждающие прерывания (warning interrupt / wakeup interrupt) – позволяют заранее предупредить прошивку о том, что сторожевой таймер вовремя не был сброшен, и что если не будет предпринято никаких действий, то дальше последует уже полноценная перезагрузка (прошивке даётся шанс восстановиться без перезагрузки). Есть прерывания по факту перезагрузки, когда одно ядро перезагружается, а второму отправляется запрос на прерывание, чтобы уведомить его о перезагрузке первого ядра.

У разных производителей эти механизмы реализованы по-разному, и у всех есть свои компромиссы. Например, в LPC55S69 предупреждающие прерывания вотчдога могут получать оба ядра, но сам вотчдог всего один. То есть реализовать схему, в которой два ядра будут независимо контролировать друг друга, не получится. В STM32H7 вотчдога два, но они привязаны к ядрам, и предупреждающее прерывание можно получать только от «своего» вотчдога. Узнать о том, что зависло второе ядро, через вотчдог можно только по факту перезагрузки этого ядра и получения reset interraupt. См. схему в разделе 46.2 reference manual

2. Программно путём контроля прохождения цикла while()

Заводим общий сегмент памяти и выделяем в нём место под две переменные. В основном цикле while() ядро читает значение systick или какого-то другого таймера и копирует это значение в общую память. Второе ядро периодически проверяет сохранённое первым ядром значение. Если значение перестаёт обновляться, то прошивка первого ядра либо не выходит из прерываний, либо зависла в какой-то из функций внутри while(1). Контроль второго ядра первым может быть устроен точно так же.

Второй способ отнимает чуть больше ресурсов, зато он позволяет организовать независимый взаимный контроль, и в целом этот способ более гибкий. Добавив чуть больше логики, можно отслеживать текущую производительность и запас по времени.

Я привёл два наиболее логичных для меня способа. Но бывают и другие. Отталкиваться стоит от конкретного микроконтроллера и от задачи.

Модель в моей голове выглядит именно так, как вы описали: у каждого ядра свой стек, и каждое из ядер выделяет память для обработчиков прерываний в своём основном стеке.

Быстро это проверить сейчас не могу.

Посмотрел отчёты линкера – никаких специальных общих стеков для прерываний там не вижу.
Если интересно, можете сами поизучать
https://gist.github.com/ngmikheev/c229a53490c75a1ff0dbeef06def2b8c

Беспилотные автомобили и роботы-доставщики Яндекса уже несколько лет катаются по Москве и не только. Но это другой проект, который делается в другом подразделении – Яндекс SDG.

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

А что это?
Не слышал о таком

Считаю, что это зависит от роли Яндекса в проектировании, настройке и эксплуатации таких систем. Если рука куплена, установлена и запущена независимо от Яндекса, а Яндекс потом к руке только дополнительный модуль управления подключил, то, да, рука отдельно, искусственный интеллект Яндекса - отдельно.

Если же Яндекс самостоятельно проектирует весь комплекс и интегрирует его с инфраструктурой заказчика, то говорить, что эта рука Яндекса, вполне обоснованно. Проектирование и интеграция – это большая работа. И в случае, если что-то пойдёт не так (например, рука начнёт ронять коробки с посудой), спрос будет именно с Яндекса, даже если плохо будет работать манипулятор Kuka или что-то ещё, что Яндекс не разрабатывал.

Здесь можно провести аналогию с такси. Мы же вызываем такси Яндекса, а не такси Hyundai со смартфоном Realme, на котором установлено приложение Яндекса.

Какова текущая роль Яндекса в автоматизации складов пока сказать сложно. Данных пока мало.

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


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

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


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


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


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


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

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


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

У нас на ЕГЭ по физике тоже вроде бы можно использовать непрограммируемые калькуляторы. По крайней мере, десять лет назад точно можно было.
При этом проверка калькулятора часто проводилась так:
— Скажите, у Вас калькулятор программируемый?
— Нет, не программируемый.
— Хорошо. Можете использовать.
В целом согласен.
Кстати, во 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
Достоинством микроконтроллеров является то, что они устроены относительно просто. Поэтому для стандартных задач можно использовать стандартные инструменты. Если же требуется что-то нестандартное или просто хочется поэкспериментировать и разобраться с тем, как всё устроено, часть вещей можно переписать самому.

Прошу прощения, я не совсем корректно выразился. Сами трассы в базе данных не хранятся, но там есть вся необходимая для их получения информация:


  • Код контрактов.
  • История состояний (в промежутках между вызовами).
  • Аргументы, передаваемые при вызове.

Подробнее можно прочитать тут: https://github.com/ethereum/go-ethereum/wiki/Tracing:-Introduction#tracing-prerequisites


Что это даёт?


Предположим, что был совершен вызов контракта, в результате которого часть денег было переведено на другой счёт.


Если имеется только текущее состояние счёта, то, глядя не него, можно узнать только то, что часть денег куда-то исчезла.
Если у нас есть история переводов, то мы можем узнать, кому, когда и сколько денег было переведено.
Если у нас есть возможность получить полную трассу выполнения контракта, то вдобавок мы узнаём, по какой причине были переведены деньги.


Вариантов здесь может быть несколько:


  • Ожидаемое поведение контракта.
  • Неожиданное, но корректное поведение контракта.
  • Проэксплуатированная уязвимость.

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

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность

Специализация

Инженер встраиваемых систем, Инженер электронных устройств