Отдельно идёт конечный автомат отработки команд, который получает по внешним интерфейсам команды и запрашивает их обработку, подавая запросы различным модулям.
Каждый модуль работает автономно, но может содержать подчинённые модули со своими автоматами. Например, конечный автомат DMA интерфейсов SPI, обрабатывает транзакции с внешней FLASH-памятью. Выше уровнем идёт конечный автомат драйвера NOR-FLASH, который заказывает транзакции SPI автомату DMA, тем самым исполняя запросы автомата более высокого уровня - конечного автомата подсистемы FLASH. В самой подсистеме FLASH два конечных автомата, один решает текущие служебные задачи - сканирование, дедупликацию записей, обеспечение наличия свободного стёртого сектора для продолжения записи логов. Другой - решает главные задачи - по выборке или внесению записей из/в различные журналы с разной ёмкостью, количеством записи и разным размером записей. Из main лишь вызывается обработчик FLASH самого верхнего уровня.
Кроме FLASH, есть подсистема работы с шиной сбора данных, где для каждого устройства на шине, предусмотрен свой микро-конечный автомат. И все эти автоматы устройств шины, объединяются общим конечным автоматом цикла опроса. Этот модуль использует и прерывания последовательного интерфейса, и прерывания таймеров, и программные прерывания для обработки данных реального времени.
Есть модуль цифровой обработки данных, который собирает данные с других автоматов, обрабатывает их и передаёт для внешних интерфейсов. Он использует пару программных прерываний, не используя периферии. В нём тоже свой конечный автомат.
Ещё работают автоматы внешних интерфейсов связи, которые получают внешние команды и данные, разбирают, собирают пакеты данных. Они так же работают с прерываниями других интерфейсов и другого таймера.
Так же, модули обращают внимание на текущий статус всей системы - в зависимости от этого, меняют свои состояния - например, переходят к инициализации или в режим калибровки.
Для эффективной работы, в зависимости от источника и назначения обрабатываемых каждым из модулей данных, для обеспечения неделимости доступа, используются функции блокировки, работающие с регистром BASEPRI у ARM или ITHRESDR у RISC-V. И для этого, почти каждому модулю, нужно "знать" приоритеты прерываний соседей, чтобы блокировать прерывания в критических секциях необходимо и достаточно. Вот эту информацию я и размещаю в общем файле, чтобы там, где готовятся данные для DSP, блокировался лишь уровень прерываний DSP. А там, где готовятся данные для быстрой шины реального времени - блокируются прерывания реального времени.
Вот такая система. Точнее, их пара на разных МК, каждая со своими задачами и со своими интефрейсами, со своей обработкой данных, но в общей системе и со сквозной передачей команд.