CMSIS
Когда в программе для STM32 написано NVIC_EnableIRQ() или SysTick_Config(), это не HAL от ST, а CMSIS — общий для всех Cortex-M слой от Arm. Он одинаков у STM32, GD32, NXP и Nordic, поэтому код работы с ядром переносится между ними без переделки.
Обновлено Редакция GAW
CMSIS (Common Microcontroller Software Interface Standard) — набор программных интерфейсов, компонентов и спецификаций Arm для микроконтроллеров на ядрах Cortex-M. По документации CMSIS 6 он начинался как независимый от производителя уровень абстракции для Cortex-M; при этом CMSIS не вводит толстого программного слоя и не стандартизует периферию (CMSIS 6, Introduction). Распространяется бесплатно по лицензии Apache 2.0.
Из чего состоит
| Компонент | Что даёт |
|---|---|
| CMSIS-Core | доступ к ядру: регистры NVIC, SCB, SysTick, функции вроде NVIC_EnableIRQ, специальные команды |
| CMSIS-Driver | общие интерфейсы драйверов периферии для промежуточного ПО |
| CMSIS-RTOS2 | общий API операционных систем реального времени |
| CMSIS-DSP, CMSIS-NN | оптимизированные функции обработки сигналов и нейросетей |
| CMSIS-DAP | прошивка отладочных адаптеров для порта отладки CoreSight |
| CMSIS-SVD, CMSIS-Pack | описание регистров устройства для отладчика и формат пакетов поддержки |
По списку компонентов в документации CMSIS 6. Для повседневной работы важнее всего CMSIS-Core: это заголовок ядра вроде core_cm3.h или core_cm4.h. Для STM32 цепочка такая: заголовок устройства от ST (stm32f103xb.h) описывает регистры периферии и номера прерываний и подключает core_cm3.h от Arm, а HAL и LL построены поверх этих заголовков — см. статью «HAL, LL и регистры CMSIS в STM32».
Что внутри CMSIS-Core
Примеры из core_cm3.h версии 6.4.0:
- Функции контроллера прерываний NVIC:
NVIC_EnableIRQ(),NVIC_SetPriority(). Приоритет сдвигается на (8 − __NVIC_PRIO_BITS) бит, потому что у кристалла реализованы только старшие биты поля; число бит задаёт заголовок устройства, у STM32F1 их 4. Если оно не задано, CMSIS берёт 3 и выдаёт предупреждение. SysTick_Config(ticks)— настраивает SysTick на прерывание каждые ticks тактов: пишет в LOAD значение ticks − 1, ставит прерыванию наименьший приоритет и запускает счётчик. Если значение не влезает в 24-битный регистр, функция возвращает 1.ITM_SendChar()— вывод символа через ITM для отладочной печати.- Обёртки команд ядра:
__enable_irq(),__disable_irq(), барьеры__DSB()и__ISB().
Код запуска, таблицу векторов и SystemInit() по шаблонам CMSIS даёт производитель — об этом статья «Код запуска». В версии 6.0.0 заголовки CMSIS-Core изменились несовместимо с CMSIS 5, поэтому старые проекты переносят по руководству Arm. Обзор семейства ядер — на странице «ARM Cortex-M».
Частые вопросы
Чем CMSIS отличается от HAL STM32?
CMSIS-Core от Arm описывает ядро: регистры NVIC, SCB, SysTick и функции работы с ними, одинаковые для всех Cortex-M. Периферию — GPIO, UART, таймеры — CMSIS не стандартизует, документация Arm говорит об этом прямо. Структуры регистров периферии даёт производитель в заголовке устройства, а HAL и LL — это уже его библиотеки поверх этих заголовков.
Можно ли писать под STM32 только на CMSIS, без HAL?
Да. Достаточно заголовка устройства от ST (например, stm32f103xb.h), который сам подключает core_cm3.h, кода запуска и файла system_stm32f1xx.c. Периферию тогда настраивают прямой записью в регистры по справочному руководству. Так пишут, когда нужен маленький и предсказуемый код.
Почему после перехода на CMSIS 6 перестал собираться старый проект?
Потому что в версии 6.0.0 заголовки CMSIS-Core для Cortex-M изменились несовместимо с прежними версиями, о чём предупреждает документация CMSIS 6 и даёт руководства по переносу. Проще всего взять версию CMSIS, которая идёт в пакете производителя вместе с заголовками устройства.
Источники
- Arm. CMSIS 6 Documentation: Introduction (arm-software.github.io/CMSIS_6) — Introduction: CMSIS (Common Microcontroller Software Interface Standard) — набор API, программных компонентов, инструментов и процессов; начинался как независимый от производителя уровень абстракции для Cortex-M, позже расширен на младшие Cortex-A; не вводит большой программный слой и не стандартизует периферию; компоненты: базовые CMSIS-Core, CMSIS-Driver, CMSIS-RTOS2 в одном пакете Arm::CMSIS; расширенные CMSIS-DSP, CMSIS-NN, CMSIS-View, CMSIS-Compiler; инструменты CMSIS-Toolbox, CMSIS-DAP, CMSIS-Zone, CMSIS-Stream; спецификации CMSIS-Pack и CMSIS-SVD; поставляется в формате CMSIS-Pack; в версии 6.0.0 заголовки CMSIS-Core для Cortex-M изменены несовместимо с прежними версиями; распространяется бесплатно по лицензии Apache 2.0
- Arm. CMSIS 6 v6.4.0: CMSIS/Core/Include/core_cm3.h (GitHub, Apache-2.0) — если в заголовке устройства не задан __NVIC_PRIO_BITS, берётся 3 с предупреждением; __NVIC_SetPriority сдвигает приоритет на (8 − __NVIC_PRIO_BITS) бит и пишет в NVIC->IPR или SCB->SHPR; SysTick_Config(ticks) пишет LOAD = ticks − 1, ставит SysTick наименьший приоритет, обнуляет VAL и включает счётчик с прерыванием, возвращает 1, если значение не влезает в регистр (маска SysTick_LOAD_RELOAD_Msk = 0xFFFFFF, 24 бита); при __Vendor_SysTickConfig = 1 функцию даёт производитель; ITM_SendChar — вывод символа через ITM; cmsis_gcc.h — __enable_irq, __disable_irq, __DSB, __ISB
- STMicroelectronics. CMSIS device headers cmsis-device-f1 (GitHub, Apache-2.0) — stm32f1xx-заголовки устройства: #define __NVIC_PRIO_BITS 4U — STM32 использует 4 бита уровней приоритета
- Arm. CMSIS 6 README (github.com/ARM-software/CMSIS_6) — структура репозитория: CMSIS/Core, CMSIS/Driver, CMSIS/RTOS2, документация; связанные репозитории CMSIS-DSP, CMSIS-NN, CMSIS-FreeRTOS, CMSIS-RTX, CMSIS-Driver; лицензия Apache-2.0
Нашли ошибку?
Смотрите также
- HAL, LL или регистрыУровни STM32Cube, что делает HAL, правила совмещения, один код тремя способами
- ARM Cortex-MЯдра M0–M85: архитектуры, FPU, DSP, MPU, TrustZone, выбор
- NVIC — контроллер прерыванийКонтроллер прерываний Cortex-M: приоритеты и вытеснение
- SysTick24-битный таймер ядра Cortex-M для системного тика
- Код запуска (startup)Что выполняется до main: стек, .data, .bss
- DSP-инструкции Armv7E-MSIMD, двойное умножение с накоплением и насыщение в ядрах Cortex-M