Огляд MCAL
Стандартизований програмний інтерфейс до внутрішньої периферії STM32, створений для модульності, переносимості та тестованості.
Огляд
Microcontroller Abstraction Layer (MCAL) розташований безпосередньо над апаратними регістрами та надає чистий уніфікований API для доступу до внутрішньої периферії STM32. Програмні компоненти вищих рівнів взаємодіють з апаратурою через цей рівень — без жодного знання подробиць роботи з регістрами.
MCAL є частиною BSP (Board Support Package) і використовує драйвери CMSIS та STM32 LL (Low-Layer) для доступу на рівні регістрів.
Ключова мета проєктування: одна периферія — один інтерфейс. Наприклад, драйвер I2C може самостійно керувати DMA, не вимагаючи від користувача окремо налаштовувати модуль DMA — уся обробка залежностей інкапсульована в самому драйвері.
Архітектура
┌─────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────┤
│ MCAL │
│ (Gpio, Usart, Rcc, I2C, SPI, ...) │
├─────────────────────────────────────┤
│ RAL — Register Abstraction Layer │
│ (CMSIS + STM32 LL Drivers) │
├─────────────────────────────────────┤
│ STM32 Hardware │
└─────────────────────────────────────┘
Підтримувана периферія
| Периферія | Опис |
|---|---|
| GPIO | Вводи/виводи загального призначення |
| USART / UART | Послідовний зв'язок |
| SPI | Serial Peripheral Interface |
| I2C | Inter-Integrated Circuit (з опційним DMA) |
| Timers | Таймери загального призначення та розширені таймери |
| ADC / DAC | Аналогово-цифрове / цифро-аналогове перетворення |
| NVIC / EXTI | Контролер переривань і зовнішні переривання |
| RCC | Керування тактуванням і скиданням |
| Flash | Доступ до flash-пам'яті |
| PWR | Живлення та системна конфігурація |
Структура репозиторію
Кожна периферія має власну окрему папку, що містить:
| Файл | Призначення |
|---|---|
<Peripheral>.c | Реалізація драйвера |
<Peripheral>.h | Оголошення публічного API |
<Peripheral>_Port.h | Апаратно-специфічна конфігурація порту |
<Peripheral>_Types.h | Визначення типів і перелічень |
Mcal/
├── Gpio/
│ ├── Gpio.c
│ ├── Gpio.h
│ ├── Gpio_Port.h
│ └── Gpio_Types.h
├── Usart/
│ ├── Usart.c
│ ├── Usart.h
│ ├── Usart_Port.h
│ └── Usart_Types.h
├── Rcc/
│ ├── Rcc.c
│ ├── Rcc.h
│ ├── Rcc_Port.h
│ └── Rcc_Types.h
├── I2c/
├── Spi/
├── Adc/
└── ...
Залежності
| Залежність | Призначення |
|---|---|
| CMSIS | Базовий інтерфейс до процесора ARM Cortex-M та системної периферії |
| STM32 LL Drivers | Легкий доступ до регістрів з мінімальними накладними витратами, без абстракції HAL |
Обидві входять до STM32Cube Firmware Package та інтегровані в BSP під рівнем RAL.
Послідовність ініціалізації
Рекомендована послідовність запуску:
1. NVIC — Interrupt controller setup
2. RCC — System clock and voltage configuration
3. GPIO — Pin multiplexing and output configuration
4. USART / SPI / I2C / ... — Peripheral initialization
5. DMA / Timers / SysTick — Optional, as needed
Цю послідовність можна виконати як частину системного запуску або ініціювати за потреби із застосунку.
Настанови щодо проєктування
- Увесь апаратно-специфічний код інкапсульований у MCAL — жодного доступу до регістрів поза цим рівнем
- Єдина конвенція іменування:
<Module>_<Action>(наприклад,Gpio_Init,Usart_Send,Rcc_SetClock) - Макроси та inline-функції застосовуються там, де критична продуктивність
- Жодних жорстко закодованих значень регістрів — скрізь використовуються макроси CMSIS/LL
- Кожен драйвер периферії самодостатній і сам керує своїми внутрішніми залежностями (наприклад, DMA)
- Усі публічні API задокументовані
Приклад використання
Ініціалізація GPIO
static gpioHal_PinConfig_t gpioHal_GpioConfiguration[GPIOHAL_IO_CNT] =
{
{
.GpioId = GPIOHAL_IO_USR_BTN,
.ConfigStruct = {
.PortId = GPIO_PORT_C,
.PinId = GPIO_PIN_13,
.PinMode = GPIO_PIN_MODE_INPUT,
.PinPull = GPIO_PIN_PULL_NONE,
.PinSpeed = GPIO_PIN_SPEED_LOW,
.PinOutType = GPIO_PIN_OUTPUT_PUSHPULL,
.PinAltFunction = GPIO_ALT_FUNC_CNT,
.PinActiveLevel = GPIO_PIN_LEVEL_HIGH
}
}
};
void GpioHal_Init(void)
{
for (uint16_t i = 0u; i < GPIOHAL_IO_CNT; i++)
{
Gpio_Init(&gpioHal_GpioConfiguration[i].ConfigStruct);
}
}
Плани розвитку
- Фреймворк інтеграційного тестування
- Покриття unit-тестами для кожного драйвера периферії
- Підтримка додаткових родин STM32
Ліцензія
Цей проєкт ліцензовано за Creative Commons Attribution–NonCommercial 4.0 International (CC BY-NC 4.0).
Ви вільні використовувати, змінювати та поширювати цю роботу в некомерційних цілях за умови належного зазначення авторства.
Повні умови дивіться у LICENSE.md або на creativecommons.org/licenses/by-nc/4.0.
Автори
- Mr.Nobody — embedbits.com
Внески вітаються! Будь ласка, відкрийте pull request.
Підтримка родин
| G4 | H5 | U5 | |
|---|---|---|---|
| Core | ✅ | — | ✅ |
| RCC | ✅ | ✅ | ✅ |
| GPIO | ✅ | ✅ | ✅ |
| EXTI | ✅ | ✅ | ✅ |
| NVIC | ✅ | ✅ | ✅ |
| TIM | ✅ | — | ✅ |
| USART | ✅ | ✅ | ✅ |
| I2C | — | ✅ | — |
| ADC | — | ✅ | — |
| CRC | — | — | ✅ |
| RNG | — | — | ✅ |
| IWDG | — | ✅ | — |
| DMA | ✅ | — | — |
| GPDMA | — | ✅ | ✅ |