Proxy MCAL: uniwersalna warstwa abstrakcji dla mikrokontrolerów
Proxy MCAL rozwiązuje problem zależności aplikacji od konkretnego HAL-a producenta. Podczas migracji firmware'u na nowy mikrokontroler standardowy HAL wymaga całkowitego przepisania sterowników GPIO, SPI, UART i innych peryferiów. Proxy MCAL zapewnia jednolity API, realizowany za pomocą funkcji bindingowych dla każdej rodziny MCU. Dzięki temu kod zachowuje przenośność bez przepisywania logiki aplikacji.
Programiści napotykają migracje z powodu starzenia się układów, niedoborów dostaw, sankcji lub nowych wymagań, takich jak Bluetooth 5.3. Proxy MCAL zapewnia modularność zgodną z ISO-26262: abstrakcyjna architektura, konfigurowalność, testowalność.
Wymagania wobec Proxy MCAL
Proxy MCAL musi spełniać surowe kryteria dla programistów middle/senior:
- Pełność: gettery i settery dla wszystkich peryferiów (CLOCK, GPIO, I2C, SPI, UART, ADC, DMA). Nieużywane funkcje weak — linker je eliminuje.
- Akceptacja: wspólny API uzgodniony w zespole.
- Prostota: 45–55 linii prototypów, intuicyjny interfejs, dokumentacja poprzez grep testów modułowych.
- Skalowalność: wiele instancji komponentów.
- Uniwersalność: obsługa sterowników ASIC, protokołów, RTOS.
- Przenośność: kompilacja na PC z pustymi weak-stubami.
- Dostęp CLI: weryfikacja funkcji przez UART w runtime.
- Testowalność: testy modułowe jako dokumentacja.
- Konfigurowalność: oddzielne konfiguracje jako tablice struktur.
Przykłady funkcji bindingowych
Jednolity API gpio_logic_level_set(Pad_t pad, GpioLogicLevel_t logic_level) jest realizowany różnie:
Dla STM32:
bool gpio_logic_level_set(Pad_t pad, GpioLogicLevel_t logic_level) {
HAL_GPIO_WritePin(Port2PortPtr(pad.port), 1 << pad.pin, (GPIO_PinState)logic_level);
return true;
}
Dla NRF5340:
bool gpio_logic_level_set(Pad_t Pad, GpioLogicLevel_t logic_level) {
bool res = false;
res = gpio_is_valid_pad(Pad);
if(res) {
nrf_gpio_pin_write((uint32_t)Pad.byte, (uint32_t)logic_level);
}
return res;
}
Dla Artery AT32 (ISR-safe):
bool gpio_logic_level_set(Pad_t Pad, GpioLogicLevel_t logic_level) {
Pad_t pad = {0};
(void)pad;
pad.byte = pad_num;
gpio_type* GPIOx = Port2PortPtr(Pad.port);
if(GPIOx) {
switch((uint8_t)logic_level) {
case GPIO_LVL_HI: {
GPIOx->scr = 1 << Pad.pin;
} break;
case GPIO_LVL_LOW: {
GPIOx->clr = 1 << Pad.pin;
} break;
}
}
return true;
}
Prototypy są stałe, ciała dostosowane do HAL-a producenta lub rejestrów.
Zalety wdrożenia
- Przenośność: aplikacja na Proxy MCAL kompiluje się dla dowolnego MCU poprzez binding.
- Testowanie: jednolite testy modułowe sprawdzają dowolny HAL.
- Interfejs CLI: scentralizowane zarządzanie peryferiami.
- Sterowniki ASIC: uniwersalne dla urządzeń SPI/I2C na wszystkich platformach.
Wady i środki zaradcze
Narzut — 10–20 cykli na wywołanie. Rozwiązanie: funkcje inline. Ryzyko kodu spaghetti minimalizowane prostotą API i słabym sprzężeniem.
Co ważne
- Proxy MCAL oddziela aplikację od HAL-a producenta, ułatwiając migrację na nowe MCU.
- Jednolity API z bindingiem zapewnia pełność i przenośność.
- Zgodny z ISO-26262: modularność, testowalność, konfigurowalność.
- Obsługuje CLI i testy modułowe do weryfikacji w runtime.
- Skaluje się na 16+ rodzin MCU bez przepisywania aplikacji.
— Editorial Team
Brak komentarzy.