OSDev Wiki
Advertisement

Системный таймер SysTick предназначен для выдачи прерываний с заданной частотой.

В архитектурах ARMv8-M без основного расширения и ARMv6-M таймер может отсутствовать (это определяется реализацией). В архитектуре ARMv7-M, а также в ARMv8-M с основным расширением, но без расширения безопасности он является обязательным. Наконец, в архитектуре ARMv8-M с основным расширением и расширением безопасности обязательно имеются два таймера: один для безопасного режима работы процессора, а другой – для небезопасного. В ARMv8-M без основного расширения, но с расширением безопасности таймеров в зависимости от реализации может не быть вообще, быть один общий для обоих режимов безопасности или иметься по отдельному таймеру для каждого режима.

Если имеются два таймера, технически они одинаковы, хотя и могут иметь разные альтернативные источники синхронизации. Если имеется один таймер, а процессор располагает расширением безопасности, возможность доступа небезопасного кода к регистрам таймера определяется битом ICSR.STTNS: когда он установлен, доступ имеется, когда он сброшен, любое чтение небезопасным кодом регистров таймера возвращает нуль, а любая запись игнорируется.

В многопроцессорной системе каждый процессор имеет собственный таймер, при этом «чужие» процессоры доступа к нему не имеют.

Принципы работы[]

Таймер ведёт отсчёт, когда его работа разрешена (установлен бит SYST_CSR.ENABLE), а процессор не находится в состоянии отладочного останова.

Из текущего значения счётчика (регистр SYST_CVR) каждый такт вычитается единица. Если в такте, в котором значение счётчика будет уменьшено с 1 до 0, прерывания от таймера были разрешены (установлен бит SYST_CSR.TICKINT), будет выдан запрос прерывания, который приведёт к установке бита ожидающего запроса прерывания от таймера (бит ICSR.PENDSTSET); далее данный запрос обрабатывается, как и любые другие запросы прерываний. В следующем после обнуления счётчика такте в него будет загружено начальное значение, хранящееся в регистре SYST_RVR, после чего он вновь будет каждый такт уменьшаться и т. д.

Текущее значение счётчика может быть программно прочитано из регистра SYST_CVR, что не оказывает никакого влияния на работу таймера.

Помимо возможной выдачи запроса прерывания, каждый раз, когда значение счётчика уменьшается до нуля, производится установка бита SYST_CSR.COUNTFLAG. Этот флаг сбрасывается, когда программа считывает значение регистра SYST_CSR или производит запись в регистр SYST_CVR. Благодаря этому возможна программная проверка истечения периода счёта таймера без использования прерываний. Заметим, что единичное значение бита SYST_CSR.COUNTFLAG не вызывает выдачу запроса прерывания, последний выдаётся лишь в момент перехода значения счётчика из единицы в нуль при разрешённых прерываниях от таймера.

Если регистр перезагружаемого значения SYST_RVR содержит нуль, это эквивалентно запрету работы таймера: в регистре текущего значения всегда будет находиться нуль, а выдача запросов прерываний и установка флага SYST_CSR.COUNTFLAG не производятся, поскольку для этого требуется переход счётчика из единицы в нуль.

Поскольку после сброса состояние регистра SYST_CVR не определено, после установки периода счёта (записи значения в SYST_RVR) необходимо выполнить запись в SYST_CVR, что обнулит счётчик и вызовет его перезагрузку из SYST_RVR.

Для уменьшения значения счётчика всегда может использоваться тактовая частота процессора (или частота, зависящая от частоты процессора; например, в микроконтроллерах серии STM32 ею будет частота процессора, делённая на 8). Кроме того, конкретная реализация процессора может предусматривать другой источник синхронизации; в этом случае выбор источника осуществляется битом SYST_CSR.CLKSOURCE.

Регистры таймера[]

Набор регистров, служащих для управления работой таймера, перечислен в таблице.

Адрес Обозначение Доступ Значение после сброса Описание
E000E010 SYST_CSR
RW
0000000x
Регистр состояния и управления таймера. После сброса содержит либо 0, либо 4 в зависимости от реализации
E000E014 SYST_RVR
RW
не определено Регистр перезагружаемого значения счётчика
E000E018 SYST_CVR
R/WC
не определено Регистр текущего значения счётчика
E000E01C SYST_CALIB
RO
не определено Регистр калибровочного значения счётчика

Регистр состояния и управления SYST_CSR[]

Адрес: E000E010.
Доступ: только привилегированный, полным словом.
Начиная с ARMv8.1-M, в зависимости от реализации отладочная запись в этот регистр может игнорироваться, если процессор не остановлен.
Наличие: в ARMv8-M без основного расширения и в ARMv6-M наличие определяется реализацией; в ARMv8-M с основным расширением и в ARMv7-M является обязательным.
Безопасность: Если процессор имеет расширение безопасности, он может (ARMv8-M без основного расширения) или обязан (ARMv8-M с основным расширением) иметь отдельные таймеры для безопасного и небезопасного режимов.
Если процессор имеет расширение безопасности и реализован лишь один системный таймер, доступность его для небезопасного режима зависит от состояния бита ICSR.STTNS: если этот бит сброшен, небезопасный код считывает из регистра SYST_CSR нулевое значение, а запись в этот регистр игнорируется.

ARM M-profile SYST CSR

Формат регистра состояния и управления таймера SysTick

Разряды Доступ Обозначение Функция
31:17
Зарезервировано
16
RC
COUNTFLAG Показывает, дошёл ли счётчик до нуля с момента последнего считывания этого регистра:
  • 0 — счётчик ещё не достигал нуля
  • 1 — счётчик достигал нуля

Этот бит сбрасывается считыванием данного регистра, а также записью значения в регистр SYST_CVR. Его установка производится, когда значение счётчика переходит из 1 в 0.
Примечание. Документация не даёт чёткого ответа, что происходит, если производится считывание из регистра SYST_CSR или запись в регистр SYST_CVR (что должно вызвать сброс бита COUNTFLAG) и одновременно счётчик (SYST_CVR) уменьшается до нуля обычным образом (что должно установить COUNTFLAG). В ядре Cortex-M1 в этой ситуации бит COUNTFLAG устанавливается.

15:3
Зарезервировано
2
RW
CLKSOURCE Выбирает источник синхронизации для таймера:
  • 0 — используется внешний источник, определяемый реализацией
  • 1 — для синхронизации используется частота процессора

Если конкретная реализация не предусматривает возможности использования внешнего источника синхронизации, этот бит всегда будет равен 1, а попытки записи в него нуля игнорируются

1
RW
TICKINT Определяет, вызывает ли достижение счётчиком нулевого значения выдачу запроса прерывания:
  • 0 — запрос прерывания не выдаётся
  • 1 — запрос прерывания выдаётся

Достижением нуля считается только декремент значения счётчика, приводящий к появлению в нём нуля, но не его сброс в результате явной записи в регистр SYST_CVR

0
RW
ENABLE Определяет, разрешена ли работа таймера (уменьшение счётчика):
  • 0 — счётчик выключен
  • 1 — счётчик включён

Регистр перезагружаемого значения SYST_RVR[]

Адрес: E000E014.
Доступ: только привилегированный, полным словом.
Начиная с ARMv8.1-M, в зависимости от реализации отладочная запись в этот регистр может игнорироваться, если процессор не остановлен.
Наличие: в ARMv8-M без основного расширения и в ARMv6-M наличие определяется реализацией; в ARMv8-M с основным расширением и в ARMv7-M является обязательным.
Безопасность: Если процессор имеет расширение безопасности, он может (ARMv8-M без основного расширения) или обязан (ARMv8-M с основным расширением) иметь отдельные таймеры для безопасного и небезопасного режимов.
Если процессор имеет расширение безопасности и реализован лишь один системный таймер, доступность его для небезопасного режима зависит от состояния бита ICSR.STTNS: если этот бит сброшен, небезопасный код считывает из регистра SYST_RVR нулевое значение, а запись в этот регистр игнорируется.

ARM M-profile SYST RVR

Формат регистра перезагружаемого значения таймера SysTick

Разряды Доступ Обозначение Функция
31:24
Зарезервировано
23:0
RW
RELOAD Значение, загружаемое в регистр SYST_CVR, когда в процессе счёта он достигнет нуля

Регистр текущего значения SYST_CVR[]

Адрес: E000E018.
Доступ: только привилегированный, полным словом.
Начиная с ARMv8.1-M, в зависимости от реализации отладочная запись в этот регистр может игнорироваться, если процессор не остановлен.
Наличие: в ARMv8-M без основного расширения и в ARMv6-M наличие определяется реализацией; в ARMv8-M с основным расширением и в ARMv7-M является обязательным.
Безопасность: Если процессор имеет расширение безопасности, он может (ARMv8-M без основного расширения) или обязан (ARMv8-M с основным расширением) иметь отдельные таймеры для безопасного и небезопасного режимов.
Если процессор имеет расширение безопасности и реализован лишь один системный таймер, доступность его для небезопасного режима зависит от состояния бита ICSR.STTNS: если этот бит сброшен, небезопасный код считывает из регистра SYST_CVR нулевое значение, а запись в этот регистр игнорируется.

ARM M-profile SYST CVR

Формат регистра текущего значения таймера SysTick

Разряды Доступ Обозначение Функция
31:0
R/WC
CURRENT Текущее значение счётчика. Неподдерживаемые разряды всегда считываются как 0. Любая запись обнуляет это поле, а также сбрасывает бит SYST_CSR.COUNTFLAG

Регистр калибровочного значения SYST_CALIB[]

Адрес: E000E01C.
Доступ: только привилегированный, полным словом.
Наличие: в ARMv8-M без основного расширения и в ARMv6-M наличие определяется реализацией; в ARMv8-M с основным расширением и в ARMv7-M является обязательным.
Безопасность: Если процессор имеет расширение безопасности, он может (ARMv8-M без основного расширения) или обязан (ARMv8-M с основным расширением) иметь отдельные таймеры для безопасного и небезопасного режимов.
Если процессор имеет расширение безопасности и реализован лишь один системный таймер, доступность его для небезопасного режима зависит от состояния бита ICSR.STTNS: если этот бит сброшен, небезопасный код считывает из регистра SYST_CALIB нулевое значение, а запись в этот регистр игнорируется.

ARM M-profile SYST CALIB

Формат регистра калибровочного значения таймера SysTick

Разряды Доступ Обозначение Функция
31
RO
NOREF Показывает, реализован ли источник опорной частоты:
  • 0 — источник реализован
  • 1 — источник не реализован

Если этот бит равен единице, бит CLKSOURCE регистра SYST_CSR всегда установлен и не может быть обнулён

30
RO
SKEW Показывает, является ли калибровочное значение точным:
  • 0 — значение является точным
  • 1 — значение является приближённым
29:24
Зарезервировано
23:0
RO
TENMS Калибровочное значение, которое, будучи загруженным в регистр SYST_RVR, обеспечивает генерацию прерываний с периодом 10 мс (частота 100 Гц). Если равно нулю, калибровочное значение не задано
Advertisement