Когда ПО прибора запускается на обычном ПК. Для этого обычно ПО разделяется на два слоя, как минимум: платформо-независимый (большая часть, условно 90%) и уровнь абстракции (HAL, 10%). Последний отдельно реализуется для МК и для ПК (где симулируется работа аппаратуры). Так же пишутся тесты для HAL, чтобы отладить HAL на МК. ПО прибора же отлаживается по большей части на ПК с использованием доступных на ПК средств отладки (
http://caxapa.ru/789975.html) и потом переносится на МК и почти сразу работает.
Уровень HAL стоит стремиться отделить не на уровне регистров и GPIO характерных для конкретного прибора, а несколько более общим (что позволяет, потенциально, другую реализацию, другим образом, на других МК). Но при этом не нагружать HAL слишком сложной логикой (больше отлаживать на МК). По-возможности HAL не должен хранить состояние и реализовывать какую-то логику управления, а должен только выполнять какие-то конкретные действия со стороны высокоуровневой программы, которая должна реализовывать логику, но не иметь возможности непосредственного выполнения каких-либо управляющих воздействий. С другой стороны абстракция должна быть достаточно общей, не слишком привязанной к конкретным техническим решениям. Из-за этого может возникать трёхслойная архитектура:
* управляющее ПО верхнего уровня (не зависит от аппаратуры);
* модуль, реализующий абстрактный интерфейс для ПО верхнего уровня, и при этом управляющий аппаратурой конкретного типа (хранит состояние, содержит логику управления) без привязки к конкретной реализации в железе (использует HAL нижнего уровня);
* уровень HAL связанный непосредственно с аппаратурой.
Например, в случае управления нагревателем, на уровень HAL выносятся функции измерения температуры и включения/выключения нагревателем. А алгоритм управления остаётся в платформенно-независимом коде. Или в случае управления электродвигателем, возможно, полезна будет трёхуровневая архитектура: на нижний уровень HAL выносятся функции управления H-мостом, например, в промежуточном уровне находится алгоритм управления двигателем конкретного типа (шаговый, BLDC, коллекторный) и через свой интерфейс позволяет задание скорости/позиции, чем уже пользуется ПО верхнего уровня.