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

Приоритеты прерываний NVIC и адреса bit-band

Выберите группу приоритетов PRIGROUP и задайте приоритет вытеснения и подприоритет — калькулятор соберёт значение, как NVIC_EncodePriority, покажет байт и адрес регистра NVIC_IPR и значение SCB_AIRCR. Второй режим считает адрес бита в области bit-band.

Исходные данные

Что считаем

у STM32F1 и F4 — 4

0–15, меньше — важнее

при этой группе только 0

из таблицы векторов: USART1 у F1 и F4 — 37

для кода

Результат

Значение приоритета
5 (0b0101)
4 бит вытеснения и 0 подприоритета
Байт NVIC_IPR
0x50значение в старших 4 битах
Где лежит
NVIC_IPR9, байт 1адрес 0xE000E425
SCB_AIRCR
0x05FA0300ключ 0x05FA и PRIGROUP в битах 10:8

Код на C

NVIC_SetPriorityGrouping(3U);
NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(3U, 5U, 0U)); /* 5 */
NVIC_EnableIRQ(USART1_IRQn);

/* the same in registers */
SCB->AIRCR = 0x05FA0300U;
*(volatile uint8_t *)0xE000E425U = 0x50U; /* NVIC->IP[37] */

Расчёт выполнен по формулам и данным из источников, приведённых на этой странице, и не заменяет проверку: параметры компонентов у разных производителей и даже партий различаются. Перед применением сверяйте результат с документацией на конкретные детали.

Контроллер прерываний NVIC ядер Cortex-M3 и M4 даёт каждому прерыванию 8-битное поле приоритета, но у STM32 реализованы только 4 старших бита — уровни от 0 до 15, где меньшее число означает более важное прерывание (PM0056, раздел 4.3). Поле PRIGROUP регистра SCB_AIRCR делит эти биты на две части: приоритет вытеснения (группу) и подприоритет.

Группы приоритетов

Сколько бит уходит на вытеснение, определяется так же, как в функции NVIC_EncodePriority из CMSIS:

биты вытеснения=min⁡(7−PRIGROUP, N),биты подприоритета=N−биты вытеснения,\text{биты вытеснения} = \min(7 - PRIGROUP,\ N), \qquad \text{биты подприоритета} = N - \text{биты вытеснения},

где N — число реализованных бит (у STM32 — 4). Отсюда пять полезных групп, которые HAL STM32Cube называет NVIC_PRIORITYGROUP_0…4: PRIGROUP = 7 — все 4 бита в подприоритете, вытеснения нет; PRIGROUP = 3 и меньше — все 4 бита в вытеснении.

Значение приоритета — приоритет вытеснения, сдвинутый на число бит подприоритета, плюс подприоритет. В регистр NVIC_IPR оно попадает в старшие биты байта: номер регистра — номер прерывания, делённый на 4, номер байта — остаток. Сам байт лежит по адресу 0xE000E400 + IRQn.

PRIGROUP меняют записью в SCB_AIRCR вместе с ключом 0x5FA в старших 16 битах — без ключа запись игнорируется. Группу задают один раз в начале программы, до настройки приоритетов: при смене группы те же значения в NVIC_IPR начинают означать другое.

Адрес bit-band

У Cortex-M3 и M4 первый мегабайт SRAM и периферии отображён побитно в область alias: запись 1 или 0 в слово alias меняет один бит без чтения-модификации-записи. Адрес слова по PM0056 и PM0214:

alias=база alias+смещение байта⋅32+номер бита⋅4,\text{alias} = \text{база alias} + \text{смещение байта} \cdot 32 + \text{номер бита} \cdot 4,

где база alias — 0x2200 0000 для SRAM и 0x4200 0000 для периферии. Например, бит 13 регистра GPIOC_ODR STM32F1 (0x4001 100C) — это слово 0x4222 01B4.

Номера прерываний и обработчики для конкретной периферии — на страницах регистров STM32F1 и STM32F4, вместе с битами, которые эти прерывания включают.

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

Чем приоритет вытеснения отличается от подприоритета?

Вытеснять работающий обработчик может только прерывание с меньшим числом в поле вытеснения (группы). Подприоритет решает лишь порядок, когда несколько прерываний одной группы ждут одновременно; если совпадает и он, первым идёт прерывание с меньшим номером IRQ (PM0056, раздел 2.3.6).

Как то же самое записать через HAL?

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4) задаёт PRIGROUP = 3 — все 4 бита под вытеснение, затем HAL_NVIC_SetPriority(USART1_IRQn, 5, 0) и HAL_NVIC_EnableIRQ(USART1_IRQn). Константы NVIC_PRIORITYGROUP_0…4 из stm32f4xx_hal_cortex.h соответствуют PRIGROUP от 7 до 3.

Почему в NVIC_IPR значение сдвинуто на 4 бита?

У STM32 из восьми бит поля приоритета работают только старшие четыре, младшие читаются как ноль. Поэтому приоритет 5 записывается в байт как 0x50. Функция NVIC_SetPriority из CMSIS делает этот сдвиг сама.

Где на STM32 есть bit-band?

У ядер Cortex-M3 и M4 — то есть у STM32F1, F2, F3, F4 и L1: каждый бит первого мегабайта SRAM (с 0x2000 0000) и периферии (с 0x4000 0000) доступен как отдельное 32-битное слово в области alias. У Cortex-M0, M0+ и M7 bit-band нет.

Источники

  1. STMicroelectronics. PM0056 Rev 7. STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual — 2.3.6 — группа и подприоритет, порядок обработки; 4.3 — уровни 0–15, NVIC_IPRx (номер регистра N DIV 4, байт N MOD 4), база NVIC 0xE000E100; 4.4.5 — SCB_AIRCR, ключ 0x5FA и PRIGROUP; 2.2.5 — формула и примеры bit-band (эталон тестов)
  2. STMicroelectronics. PM0214 Rev 10. STM32 Cortex-M4 MCUs and MPUs programming manual — те же правила для Cortex-M4: группировка приоритетов, AIRCR, формула и примеры bit-band — второй источник
  3. Arm. CMSIS 5: CMSIS/Core/Include/core_cm4.h, функция NVIC_EncodePriority (Apache-2.0) — число бит вытеснения min(7 − PRIGROUP, __NVIC_PRIO_BITS) и подприоритета — формула калькулятора
  4. STMicroelectronics. STM32CubeF4 HAL: stm32f4xx_hal_cortex.h — NVIC_PRIORITYGROUP_0…4 = PRIGROUP 7…3: от 0 до 4 бит вытеснения — эталон тестов
  5. STMicroelectronics. CMSIS-заголовки stm32f103xb.h и stm32f407xx.h — __NVIC_PRIO_BITS = 4, номера прерываний (USART1_IRQn = 37)

Где пригодится

Встроить калькулятор на свой сайт

Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах

<iframe src="https://gaw.ru/embed/nvic-priority/" title="Приоритеты прерываний NVIC и адреса bit-band" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/nvic-priority/">Приоритеты прерываний NVIC и адреса bit-band</a> — GAW.ru</p>
Автоподстройка высоты рамки

Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.

<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>

Обновлено .

Нашли ошибку в расчёте?