Перейти к содержанию

ARM Cortex-M

Cortex-M — 32-битные процессорные ядра ARM для микроконтроллеров: на них построены STM32, RP2040, nRF52840, SAM D21 и отечественные К1986ВЕ92. Здесь — чем различаются ядра от M0 до M85, как выбрать ядро и чем программировать и отлаживать такие микроконтроллеры.

Cortex-M — линейка 32-битных процессорных ядер ARM для микроконтроллеров. Сама ARM микросхем не выпускает: ядро поставляется производителям как синтезируемое описание на уровне регистровых передач (RTL), а они добавляют Flash-память, ОЗУ и периферию и выпускают готовый кристалл. Поэтому одно и то же ядро Cortex-M3 работает и в STM32F103, и в миландровском К1986ВЕ92QI: регистры ядра, таблица векторов, контроллер прерываний NVIC и системный таймер SysTick у них устроены одинаково, а различаются память, периферия и тактовая частота.

Все ядра Cortex-M выполняют только команды Thumb — 16- и 32-битные, — при входе в прерывание сохраняют регистры аппаратно, так что обработчик пишется обычной функцией на C, и используют общую карту памяти на 4 ГБ. Программы для ARMv6-M (Cortex-M0 и M0+), включая системные, по справочнику ARM выполняются на ARMv7-M без изменений, а с ARMv6-M совместимы и все ядра ARMv8-M.

Cortex-M, Cortex-A и Cortex-R

ARM делит архитектуру на три профиля. Они различаются не столько скоростью, сколько тем, для каких систем рассчитаны:

ПрофильДля чегоПамятьНабор командПрограммы
A (application)процессоры для ОС с виртуальной памятьюблок управления памятью MMU, виртуальные адресаARM и ThumbLinux и другие ОС общего назначения
R (real-time)быстрые системы реального временитолько физические адреса, защита областей памятиARM и ThumbОС реального времени
M (microcontroller)микроконтроллеры: малый размер и предсказуемое время реакциифизические адреса, необязательный блок защиты MPUтолько Thumbбез ОС или с ОС реального времени

Справочник ARMv7-M называет главными требованиями к профилю M малое и постоянное число тактов на команду, минимальную задержку прерываний за счёт короткого конвейера и способность работать без кэша. Отсюда особенности Cortex-M, которых нет у старших профилей: таблица векторов хранит адреса обработчиков, а не команды перехода; ядро вместе со встроенным контроллером прерываний NVIC само сохраняет регистры; карта памяти фиксирована, а системный таймер SysTick, обязательный начиная с ARMv7-M, устроен одинаково у всех производителей — это упрощает перенос ОС реального времени.

До Cortex-M микроконтроллеры ARM строили, например, на ядре ARM7TDMI: архитектура ARMv4T, конвейер из трёх ступеней, два набора команд — 32-битный ARM и 16-битный Thumb. Microchip до сих пор выпускает такие МК серии AT91SAM7S, но код для них на Cortex-M без переделки не переносится: у Cortex-M нет набора команд ARM и другая модель исключений.

Ядра Cortex-M: сравнительная таблица

Ядро CortexАрхитектураКонвейер, ступенейFPUDSPMPU, областейTrustZoneDMIPS/МГцПримеры МК
M0ARMv6-M3————0,96STM32F0
M0+ARMv6-M2——8, опция—0,99STM32G0, STM32C0, SAM D21, RP2040
M3ARMv7-M3——8, опция—1,24STM32F1, К1986ВЕ92QI
M4ARMv7E-M3SP, опцияесть8, опция—1,26STM32F4, STM32G4, STM32L4, nRF52840
M7ARMv7E-M6, суперскалярныйSP или SP и DP, опцияесть8 или 16, опция—2,31STM32H7
M23ARMv8-M Baseline2——до 16, опцияопция1,03SAM L11
M33ARMv8-M Mainline3SP, опцияопциядо 16, опцияопция1,54STM32U5, RP2350
M55ARMv8.1-M Mainline4HP, SP, DP, опцияесть, Helium — опциядо 16опция1,69STM32N6
M85ARMv8.1-M Mainline7, две команды за тактHP, SP, DP, опцияесть, Helium — опциядо 16есть3,13Renesas RA8M1

SP, DP и HP — блок FPU одинарной, двойной и половинной точности. «Опция» значит, что блок включает в кристалл производитель, поэтому смотреть надо даташит конкретного МК. Например, у STM32F103C8 с ядром Cortex-M3 блока MPU нет. Обозначение Cortex-M4F, которое встречается у производителей, — это ядро M4 с FPU.

Цифры DMIPS/МГц взяты из сводной таблицы ARM 2023 года. Тест Dhrystone сильно зависит от компилятора и его настроек: для того же Cortex-M3 ARM приводила 1,25 DMIPS/МГц по строгим правилам теста и до 1,89 — с поблажками компилятору. Поэтому столбец годится для сравнения ядер между собой, но не для оценки скорости конкретной программы — её даёт только замер на целевом кристалле.

Кроме ядер из таблицы, в линейке есть Cortex-M1, M35P и M52. Cortex-M52 — ядро ARMv8.1-M с конвейером из 4 ступеней и одинарным вариантом Helium; ARM приводит для него 1,6 DMIPS/МГц.

Архитектуры: от ARMv6-M до ARMv8.1-M

Ядра Cortex-M по архитектурам: от ARMv6-M до ARMv8.1-MКомпактная линия: ARMv6-M с ядрами Cortex-M0, M0+ и M1 и её продолжение ARMv8-M Baseline с ядром M23 и необязательным TrustZone. Основная линия: ARMv7-M с ядром M3, ARMv7E-M с DSP-командами и необязательным FPU — M4 и M7, ARMv8-M Mainline — M33 и M35P, ARMv8.1-M Mainline с векторным расширением Helium — M52, M55 и M85. Команды ARMv6-M входят в ARMv7-M, а Baseline — подмножество Mainline.ARMv6-Mподмножество Thumb, одна шинаM0M0+M1ARMv8-M Baseline+ TrustZone (опция), новый MPUM23ARMv7-MThumb-2, делениеM3ARMv7E-M+ DSP, FPU (опция)M4M7ARMv8-M Mainline+ TrustZone (опция)M33M35PARMv8.1-M Mainline+ Helium, PACBTI (опции)M52M55M85команды ARMv6-M входят в ARMv7-MBaseline — подмножество MainlineСплошные стрелки — развитие архитектуры, пунктир — совместимость по командам
Ядра Cortex-M по архитектурам. Компактная линия — ARMv6-M и ARMv8-M Baseline, основная — от ARMv7-M до ARMv8.1-M Mainline.
  • ARMv6-M — Cortex-M0, M0+ и M1. Сокращённый набор Thumb без команд деления, до 32 прерываний и 4 уровня приоритета, одна шина AHB-Lite, по которой по очереди идут и команды, и данные (архитектура фон Неймана). У M0+ конвейер укорочен до двух ступеней и есть однотактный порт ввода-вывода для быстрой работы с выводами.
  • ARMv7-M — Cortex-M3. Полный набор Thumb-2 с 32-битными командами, аппаратное деление за 2–12 тактов, команды насыщения и работы с битовыми полями, до 240 прерываний и от 8 до 256 уровней приоритета, маски BASEPRI и FAULTMASK, три шины AHB-Lite.
  • ARMv7E-M — Cortex-M4 и M7. К ARMv7-M добавлено расширение DSP — SIMD-команды над 8- и 16-битными числами и арифметика с насыщением — и необязательный блок FPU: одинарной точности (FPv4-SP) у M4, одинарной или двойной (FPv5) у M7.
  • ARMv8-M Baseline — Cortex-M23. Совместим с ARMv6-M и добавляет новую модель MPU, контроль границ стека и необязательный TrustZone.
  • ARMv8-M Mainline — Cortex-M33 и M35P. Baseline плюс расширение Main, которое даёт совместимость с ARMv7-M; DSP и FPU — опции.
  • ARMv8.1-M — Cortex-M52, M55 и M85. Векторное расширение Helium (MVE) для цифровой обработки сигналов и машинного обучения, у M52 и M85 — ещё PACBTI как опция: аутентификация указателей и контроль целей перехода против атак на поток управления.

Совместимость работает снизу вверх. ARMv6-M — подмножество ARMv7-M, и по справочнику ARM её программы, включая системные, выполняются на ARMv7-M без изменений; совместимость с ARMv6-M обязательна и для любой реализации ARMv8-M, а с ARMv7-M — для ядер с расширением Main. Обратно это не работает: команды деления или условного блока IT, которые компилятор охотно использует для M3, ядро M0 выполнить не сможет.

Чем отличаются Cortex-M0, M3 и M4

  • Cortex-M0 и M0+ — минимальные ядра для простого управления: сокращённый набор команд без деления, до 32 прерываний и 4 уровня приоритета, одна шина. Умножение 32 × 32 бита производитель выбирает быстрым за 1 такт или компактным за 32 такта.
  • Cortex-M3 — универсальное ядро: полный Thumb-2, аппаратное деление, до 240 прерываний и до 256 уровней приоритета, три шины — выборка команд из Flash-памяти идёт параллельно с обращениями к данным в SRAM. Чисел с плавающей точкой аппаратно не считает: операции с float компилятор выполняет подпрограммами.
  • Cortex-M4 — то же ядро M3 с DSP-командами и необязательным FPU одинарной точности. На целочисленном коде по скорости почти не отличается от M3, а операции с float блок FPU, по оценке ARM, ускоряет примерно в 10 раз.

Регистры, режимы, карта памяти, bit-banding, NVIC с задержкой прерывания 12 тактов и отладочные блоки — общие для M3 и M4 — подробно разобраны в статье «Архитектура ARM Cortex-M3». Там же — сравнительная таблица M0, M0+, M3 и M4 и пример программы для STM32F103 на CMSIS.

Как выбрать ядро Cortex-M

  1. Сначала периферия, память и корпус, потом ядро. Нужные интерфейсы, объём Flash и ОЗУ, напряжение питания и цена определяют выбор сильнее, чем ядро. Общие советы — в разделе «Микроконтроллеры».
  2. Простое управление и батарейные устройства — Cortex-M0+: STM32G0, STM32C0, SAM D21. В RP2040 два ядра M0+ и программируемые блоки ввода-вывода PIO.
  3. Универсальная задача — Cortex-M3 и M4. Для нового изделия STM32F1 на M3 стоит сравнить с сериями на M4 с FPU, например STM32G4 или STM32F4: программная модель ядра та же, а вычисления с плавающей точкой идут аппаратно.
  4. Цифровая обработка сигналов — фильтры, БПФ, управление двигателями, звук: Cortex-M4F, M33 с FPU и DSP, M7.
  5. Защита ключей и прошивки — ядра ARMv8-M с TrustZone: M23, M33, M55, M85.
  6. Высокая производительность — Cortex-M7, у которого кэши, память TCM и FPU двойной точности предусмотрены как опции (например, STM32H7), и Cortex-M85 (Renesas RA8M1). Для нейросетей на кристалле — M55 и M85 с Helium.

ESP32, RISC-V и отечественные микроконтроллеры

Не всякий 32-битный микроконтроллер — ARM. ESP32 построен на ядрах Xtensa LX6, ESP32-S3 — на Xtensa LX7, ESP32-C3 и C6 — на RISC-V. NVIC, SysTick и CMSIS-Core у них нет, а программы собирают в среде Espressif ESP-IDF или Arduino. В RP2350 стоят сразу два ядра Cortex-M33 и два ядра RISC-V Hazard3, а какие из них работают, выбирается программно или записью в однократно программируемую память OTP.

Из отечественных микроконтроллеров на Cortex-M известны, например:

  • Миландр К1986ВЕ92QI — Cortex-M3, 128 КБ Flash, 32 КБ ОЗУ, до 80 МГц; производитель называет ближайшим аналогом STM32F103. Снят с производства, замена — К1986ВЕ92F1I с совместимым корпусом.
  • НИИЭТ К1921ВК01Т — Cortex-M4F, 100 МГц, 1 МБ Flash и 192 КБ ОЗУ, развитая периферия для управления электроприводом.

Новые разработки НИИЭТ, например К1921ВГ015, построены уже на ядрах RISC-V.

Инструменты: CMSIS, компиляторы и отладка по SWD

CMSIS (Common Microcontroller Software Interface Standard) — набор интерфейсов ARM, общий для всех производителей. Его основа CMSIS-Core: заголовки core_cm3.h, core_cm4.h и другие с именами регистров ядра и функциями NVIC_SetPriority(), SysTick_Config(), __enable_irq(). Производитель кристалла дополняет их своим заголовком с регистрами периферии — у STM32F103 это stm32f103xb.h. Кроме того, в CMSIS входят библиотеки DSP и нейросетей, интерфейс ОС реального времени RTOS2, прошивка отладочных адаптеров CMSIS-DAP и формат SVD с описанием регистров для отладчиков.

Компиляторы. Бесплатный — GCC для «голого железа» arm-none-eabi-gcc; коммерческие — Arm Compiler в Keil MDK и IAR Embedded Workbench. Среды разработки, утилиты прошивки и их лицензии сравниваются в разделе «Программы для электронщика».

Отладка. Ядра Cortex-M отлаживают через порт SWD — две линии SWDIO и SWCLK плюс общий провод — или через JTAG с линиями TCK, TMS, TDI и TDO. Отладчик останавливает ядро, ставит аппаратные точки останова и наблюдения, читает память на ходу, а через вывод SWO принимает трассировку. Адаптеры — ST-LINK, J-Link, адаптеры CMSIS-DAP; со стороны компьютера — OpenOCD или фирменные утилиты в связке с отладчиком GDB.

С чего начать

  1. Разберитесь с ядром: регистры, исключения, NVIC, карта памяти и стартовый код — в статье «Архитектура ARM Cortex-M3». Всё это без изменений относится и к Cortex-M4.
  2. Возьмите плату с недорогим STM32 — например, STM32F103C8 («Blue Pill») с отдельным адаптером ST-LINK — и соберите пример из статьи: SysTick и мигание светодиодом на регистрах.
  3. Подключите периферию: в статьях про SPI и CAN есть разделы о модулях STM32, а остальные интерфейсы собраны в разделе «Интерфейсы».

Готовятся к публикации

STM32: обзор семейств · STM32F103 и плата Blue Pill · Cortex-M0+ · Cortex-M4 и FPU · NVIC и прерывания · Система команд Thumb-2 · Отладка по SWD · ARM7TDMI · AT91SAM7S

Частые вопросы

Чем Cortex-M4 отличается от Cortex-M3?

M4 построен на архитектуре ARMv7E-M: к командам M3 добавлены DSP-команды — SIMD над 8- и 16-битными числами, умножение с накоплением за один такт, арифметика с насыщением — и необязательный блок FPU одинарной точности. Конвейер из трёх ступеней, NVIC, карта памяти и задержка входа в прерывание 12 тактов у них общие, поэтому программа для M3 работает на M4 без изменений. На целочисленном коде ядра почти равны: 1,24 и 1,26 DMIPS/МГц по сводной таблице ARM.

Какое ядро Cortex-M самое экономичное?

Самое простое — Cortex-M0+: конвейер из двух ступеней, одна шина, четыре уровня приоритета прерываний. ARM приводит для него 47,4 мкВт/МГц динамической мощности на техпроцессе 180 нм ULL против 66 мкВт/МГц у Cortex-M0, а производительность на мегагерц у них почти одинакова: 0,99 и 0,96 DMIPS/МГц. На M0+ построены STM32G0, STM32C0, SAM D21 и RP2040. Но потребление готового микроконтроллера сильнее зависит от техпроцесса, режимов сна и периферии, чем от ядра.

ESP32 — это ARM?

Нет. ESP32 построен на ядрах Xtensa LX6, ESP32-S3 — на Xtensa LX7, ESP32-C3 и ESP32-C6 — на RISC-V. Регистров ядра Cortex-M, контроллера NVIC и библиотеки CMSIS-Core у них нет, а программы собирают в среде ESP-IDF или Arduino. ARM-ядра стоят, например, в RP2040 и RP2350 от Raspberry Pi, nRF52840 от Nordic и всех STM32.

Перенесётся ли программа с одного Cortex-M на другой?

Код ядра переносится снизу вверх: программы для ARMv6-M (M0, M0+) выполняются на ARMv7-M (M3, M4) без изменений, а все ядра ARMv8-M совместимы с ARMv6-M. Обратно не получится: команд деления и условных блоков IT у M0 нет. Периферия у производителей своя, поэтому таймеры, UART и тактирование STM32 и nRF52 программируются по-разному. Доступ к самому ядру — NVIC, SysTick, регистрам SCB — одинаков благодаря CMSIS-Core.

Что такое TrustZone в Cortex-M?

Расширение безопасности архитектуры ARMv8-M. Ядро получает два состояния — защищённое (Secure) и обычное (Non-secure), память и периферия размечаются как защищённые или нет, и обычный код не может прочитать ключи и данные защищённой области. В ядрах M23, M33 и M55 TrustZone — опция производителя кристалла, в M85 есть всегда. У ядер ARMv6-M и ARMv7-M, в том числе у M0, M3 и M4, TrustZone нет.