SysTick — системный таймер
SysTick — простой таймер, встроенный в само ядро Cortex-M. Он одинаков у всех микроконтроллеров на этом ядре, поэтому на нём строят системный тик: счёт миллисекунд в HAL, задержки и переключение задач в операционных системах реального времени.
Обновлено Редакция GAW
SysTick (system tick timer) — 24-битный таймер, входящий в состав ядра ARM Cortex-M. Он считает вниз от значения перезагрузки до нуля; на переходе из 1 в 0 выставляет флаг COUNTFLAG, при разрешении вызывает исключение SysTick и снова загружается. Поскольку таймер одинаков у всех Cortex-M3, операционные системы реального времени и библиотеки берут его для системного тика.
Регистры
| Регистр (CMSIS) | Адрес | Назначение |
|---|---|---|
| SysTick->CTRL | 0xE000 E010 | ENABLE — пуск, TICKINT — запрос исключения, CLKSOURCE — источник такта, COUNTFLAG — дошёл до нуля |
| SysTick->LOAD | 0xE000 E014 | значение перезагрузки, 24 бита |
| SysTick->VAL | 0xE000 E018 | текущее значение; запись обнуляет счётчик |
| SysTick->CALIB | 0xE000 E01C | калибровка: у STM32F1 — 9000 отсчётов, 1 мс при 72 МГц и такте HCLK/8 |
Период прерываний:
Для 1 мс при 72 МГц LOAD = 71 999. Бит CLKSOURCE выбирает частоту ядра (1) или внешний опорный такт (0) — у STM32F1 это HCLK/8 (PM0056, раздел 4.5). Подробнее о ядре, исключениях и приоритетах — в статье об архитектуре Cortex-M3.
SysTick и приоритеты
Функция CMSIS SysTick_Config ставит SysTick самый низкий приоритет. HAL STM32 считает в его прерывании миллисекунды для HAL_GetTick и HAL_Delay, поэтому внутри обработчиков других прерываний с таким же или более высоким приоритетом счётчик стоит. Как HAL раскладывает приоритеты и как поднять приоритет SysTick, разобрано в статье о прерываниях STM32, а значения регистров приоритетов считает калькулятор NVIC.
Частые вопросы
Как настроить SysTick на 1 мс?
Записать в LOAD значение f / 1000 − 1 при тактировании от частоты ядра: при 72 МГц это 71 999. Проще вызвать функцию CMSIS SysTick_Config(SystemCoreClock / 1000): она запишет LOAD, поставит SysTick самый низкий приоритет, обнулит счётчик и запустит его с разрешённым прерыванием.
Какой наибольший период у SysTick?
Счётчик 24-битный, поэтому наибольший период — 2^24 тактов. При частоте ядра 72 МГц это около 0,233 с, при такте HCLK/8, который у STM32F1 выбирается битом CLKSOURCE = 0, — около 1,864 с. Если SysTick_Config получает слишком большое значение, функция возвращает 1 и таймер не трогает.
Почему HAL_Delay не работает в обработчике прерывания?
HAL STM32 считает миллисекунды в обработчике прерывания SysTick, а у него по умолчанию самый низкий приоритет. Пока выполняется обработчик другого прерывания с таким же или более высоким приоритетом, SysTick не может его вытеснить, счётчик миллисекунд стоит, и HAL_Delay ждёт вечно.
Источники
- STMicroelectronics. PM0056: STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual, Rev 7, 2024 — разд. 4.5 — SysTick: регистры CTRL, LOAD, VAL, CALIB, источник такта, STK_CALIB = 9000
- Arm. CMSIS-Core (Cortex-M) documentation — функция SysTick_Config: LOAD = ticks − 1, низший приоритет, запуск от частоты ядра с прерыванием
- STMicroelectronics. STM32CubeF1 HAL driver (stm32f1xx-hal-driver) — HAL_Init: приоритет SysTick TICK_INT_PRIORITY = 0x0F; HAL_IncTick в обработчике SysTick, HAL_Delay и HAL_GetTick
Нашли ошибку?
Смотрите также
- Cortex-M3Регистры, карта памяти, bit-banding, NVIC, SysTick, MPU, старт, пример
- Прерывания STM32Векторы и IRQn, приоритеты и HAL, EXTI и общие векторы, флаги, события, примеры
- Приоритеты прерываний NVICPRIGROUP, вытеснение и подприоритет, NVIC_IPR, AIRCR, bit-band
- ПрерываниеЗапрос периферии, вектор и обработчик прерывания