Собственно можно подсмотреть реализацию взаимодействия HAL с
прикладным уровнем через ABI. Мы реализовывали на этом принципе
такую схему: - по подаче питания стартует HAL и он обеспечивает в т.ч. функции перечисленные в структуре hal_rte_abi_t (см. ниже);
- HAL запускает UI позволяющий в т.ч. записать, выбрать из ранее записанных и запустить (в ОЗУ) требуемый прикладной (USER) код;
- запущенный USER получает полный контроль над железом и возможность вызова функций HAL.
Тонкости сборки не помню, делал специально обученный человек.
typedef struct
{
// Вывод на экран
LCD_BUF_STATE (*DrawPayload)(uint8_t *, uint16_t );
// Обработка кнопок
u16 (*GetPressed)(void);
u16 (*GetReleased)(void);
u8 (*GetKeyState)(u8 );
u16 (*GetKeysState)(void);
// получение токов и напряжений
PWR (*GetUI)(void);
// управление ЦАП
u16 (*Set_mV_DAC)( UPOR , u16 );
// управление системными событиями
...........................................................................
// пользовательские таймеры
...........................................................................
// обработка дискретных входов
........................................................................
}
hal_rte_abi_t;
................................................
#define PLC_RTE ((hal_rte_abi_t *)(PLC_RTE_ADDR))
.........................
powers = PLC_RTE->GetUI();
Описал кривовато, на "прямо" времени надо много, да и вспоминать тоже, делали лет 5 как.