В микроконтроллеры серии STM32F4 (как впрочем, и многих других серий STM32) встроены два таймера, которые удобно использовать в качестве сторожевых - независимый сторожевой таймер (Independent WatchDoG, IWDG [2]) и оконный сторожевой таймер (Window WatchDoG, WWDG). В этой статье приведен соответствующих разделов даташита RM0090. Вся информация, приведенная ниже, относится к семейству STM32F4xx, если не указано нечто иное. Все непонятные термины и сокращения см. в статье-словарике [3].
Оба сторожевых таймера (IWDG и WWDG) предоставляют комбинацию дополнительного уровня безопасности, точного отсчета времени, гибкости в использовании. Сторожевые таймеры после их настройки работают независимо от основных потоков вычислений в приложении, давая возможность обнаруживать и устранять проблемы, возникающие в приложении (зависание, задержка обработки). В подобных ситуациях счетчик таймера достигает значения таймаута, и в этот момент можно генерировать прерывание (только для WWDG) или системный сброс.
Независимый сторожевой таймер (IWDG) тактируется от своего собственного, внутреннего низкоскоростного генератора LSI (Low-Speed Internal clock), поэтому IWDG остается активным даже когда произошел отказ генерации основной тактовой частоты микроконтроллера (HSI или HSE). Частота тактирования оконного таймера (WWDG) поступает через прескалер от тактовой частоты APB1. Окно времени WWDG программируется, что позволяет детектировать ненормальное запаздывание отклика программы, либо слишком раннюю активацию действия программы.
Сторожевой таймер IWDG лучше всего подходит для приложений, которые требуют полной независимости работы таймера от основного приложения, имея при этом небольшие требования к точности установки времени таймаута. Оконный таймер WWDG лучше подходит для приложений, которые требуют реакции в точно установленном окне времени.
[Сторожевой таймер IWDG]
Основные функции IWDG:
• Независимо работающий счетчик, считающий вниз • Тактируется от внутреннего RC-генератора, поэтому остается активным в режимах пониженного энергопотребления Standby и Stop • Сбрасывает микроконтроллер (если сторожевой таймер активирован), когда счетчик при счете вниз достигает значения 0x000 • Hardware watchdog
На рис. 213 показаны функциональные блоки сторожевого таймера IWDG.
Рис. 213. Блок-схема Independent WatchDoG.
Примечание: функция сторожевого таймера реализована в домене напряжения питания VDD, который остается функциональным в режимах Stop и Standby.
IWDG запускается путем записи специального значения 0xCCCC в регистр ключа (IWDG_KR), при этом счетчик начинает счет вниз от значения сброса 0xFFF. Когда счетчик достигает конечного значения 0x000, генерируется сигнал сброса (IWDG reset). Всякий раз, когда значение ключа 0xAAAA записывается в регистр IWDG_KR, значение из регистра IWDG_RLR перезагружается в счетчик, что предотвращает его обнуление и как следствие предотвращает сброс микроконтроллера.
Hardware watchdog. Функция "Hardware watchdog" разрешается через биты опций микроконтроллера, тогда сторожевой таймер автоматически разрешается при включении питания и будет генерировать сброс, если не было своевременно (до момента достижения счетчиком нуля) записано значение 0xAAAA в регистр ключа IWDG_KR.
Защищенный доступ к регистрам. Доступ на запись в регистры IWDG_PR и IWDG_RLR снабжен защитой, что помогает избежать влияния на эти регистры ошибочных действий в программе. Чтобы изменить IWDG_PR и IWDG_RLR, сначала надо записать код 0x5555 в регистр ключа IWDG_KR. Запись в регистр ключа другого значения оборвет процедуру доступа к регистрам IWDG_PR и IWDG_RLR, и защита снова включается. Это верно и для случая операции перезагрузки счетчика (запись в IWDG_KR значения 0xAAAA).
Имеется регистр статуса, показывающий состояние обновления прескалера или состояние выполнения перезагрузки счетчика.
Режим отладки. Когда микроконтроллер STM32 входит в режим отладки (debug mode, в котором ядро Cortex®-M4 со встроенным блоком FPU останавливается), IWDG будет либо продолжать свой счет, либо остановится, в зависимости от конфигурационного бита DBG_IWDG_STOP в модуле DBG. Для получения дополнительной информации см. секцию 38.16.2 "Debug support for timers, watchdog, bxCAN and I2C" руководства [1].
Таблица 107. Минимальный и максимальный период таймаута IWDG в миллисекундах, когда LSI работает на частоте 32 кГц(1).
Делитель прескалера
PR[2:0]
Min таймаут (мс) RL[11:0]=0x000
Max таймаут (мс) RL[11:0]=0xFFF
/4
0
0.125
512
/8
1
0.25
1024
/16
2
0.5
2048
/32
3
1
4096
/64
4
2
8192
/128
5
4
16384
/256
6
8
32768
Примечание (1): указанные в таблице интервалы времени соответствует частоте тактов IWDG 32 кГц. Однако эту частоту вырабатывает внутренний RC-генератор микроконтроллера, и поэтому частота может изменяться от внешних условий (тепература, напряжение питания). Для получения информации о минимальной и максимальной частоте LSI обратитесь к даташиту на используемый микроконтроллер.
Регистры IWDG. К регистрам можно обращаться как к половинкам слов (16 бит) или как к полным словам (32 бита). Смещение указано относительно базового адреса. Например, для микроконтроллера STM32F429 базовый адрес равен 0x40003000 (см. определение IWDG_BASE в заголовочном файле stm32f429xx.h библиотеки CMSIS).
В обозначениях бит используются аббревиатуры r, w, rw, что означает следующее:
r доступ к биту возможен только для чтения (Read) w доступ к биту возможен только для записи (Write) rw доступ к биту возможен и для чтения, и для записи.
Смещение 0x00 Значение сброса 0x00000000 (сброс в режиме Standby)
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
зарезервировано
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
KEY[15:0] w
Биты 31:16 зарезервированы и должны сохраняться в состоянии сброса (все нули).
KEY[15:0] (биты 15:0) значение ключа. Биты работают только на запись, считываются как 0x0000. Когда IWDG активирован, в эти биты должны записываться только определенные специальные значения:
0xAAAA для предотвращения сброса по обнулению счетчика. 0x5555 для разрешения доступа к регистрам IWDG_PR и IWDG_RLR. 0xCCCC запуск сторожевого таймера. Эта запись нужна для запуска только если опциями не выбрана функция hardware watchdog.
Биты 31:3 зарезервированы и должны сохраняться в состоянии сброса (все нули).
PR[2:0] (биты 2:0) выбор коэффициента деления прескалера для подачи тактов на счетчик IWDG. Запись в эти биты защищена специальной последовательностью ключа (см. выше секцию "Защищенный доступ к регистрам"). Бит PVU в регистре статуса IWDG_SR в состоянии 0 показывает, что в данный момент можно изменить коэффициент деления прескалера.
000: деление частоты LSI на 4 001: деление частоты LSI на 8 010: деление частоты LSI на 16 011: деление частоты LSI на 32 100: деление частоты LSI на 64 101: деление частоты LSI на 128 110: деление частоты LSI на 256 111: деление частоты LSI на 256
Примечание: чтение регистра IWDG_PR вернет значение прескалера из домена напряжений VDD. Это прочитанное значение может быть недостоверным, если в настоящий момент активна операция записи в этот регистр. По этой причине значение, прочитанное из IWDG_PR, достоверно только если сброшен бит PVU в регистре IWDG_SR.
Смещение 0x08 Значение сброса 0x00000FFF (сброс в режиме Standby)
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
зарезервировано
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
заререзвировано
RL[11:0] rw
Биты 31:12 зарезервированы и должны сохраняться в состоянии сброса (все нули).
RL[11:0] (биты 11:0) значение, которым перезагружается счетчик IWDG. Запись в эти биты защищена специальной последовательностью ключа (см. выше секцию "Защищенный доступ к регистрам"). Счетчик перезагрузится значением из IWDG_RLR, когда в регистр ключа IWDG_KR было записано специальное значение 0xAAAA. Счетчик считает вниз от значения регистра IWDG_RLR, поэтому время таймаута определяется значением IWDG_RLR и тактовой частотой, подаваемой на счетчик (определяется регистром прескалера IWDG_PR). Бит RVU в регистре статуса IWDG_SR в состоянии 0 показывает, что в данный момент можно изменить коэффициент деления прескалера.
Примечание: чтение регистра IWDG_RLR вернет значение перезагрузки счетчика из домена напряжений VDD. Это прочитанное значение может быть недостоверным, если в настоящий момент активна операция записи в этот регистр. По этой причине значение, прочитанное из IWDG_RLR, достоверно только если сброшен бит RVU в регистре IWDG_SR.
Смещение 0x0C Значение сброса 0x00000000 (сброс не в режиме Standby)
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
зарезервировано
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
заререзвировано
RVU r
PVU r
Биты 31:2 зарезервированы и должны сохраняться в состоянии сброса (все нули).
RVU (бит 1) Reload Value Update. Бит устанавливается и сбрасывается аппаратно. Лог. 1 в этом бите показывает, что в настоящий момент активна операция обновления значения для перезагрузки (регистр IWDG_RLR). Бит сбросится в лог. 0 аппаратно, когда завершится операция обновления в домене напряжений VDD (время обновления занимает до 5 тактов RC-генератора LSI). Значение перезагрузки в регистре IWDG_RLR можно обновить только если бит RVU сброшен в 0.
PVU (бит 0) Prescaler Value Update. Бит устанавливается и сбрасывается аппаратно. Лог. 1 в этом бите показывает, что в настоящий момент активна операция обновления значения прескалера (регистр IWDG_PR). Бит сбросится в лог. 0 аппаратно, когда завершится операция обновления в домене напряжений VDD (время обновления занимает до 5 тактов RC-генератора LSI). Значение прескалера в регистре IWDG_PR можно обновить только если бит PVU сброшен в 0.
Примечание: если приложение использует несколько значений перезагрузки или несколько значений прескалера, то перед обновлением значения перезагрузки важно подождать, когда биты RVU сбросится. Однако после обновления прескалера и/или значения перезагрузки не обязательно ждать сброса RVU или PVU перед продолжением выполнения кода (даже в случае входа в режим пониженного потребления энергии операция записи будет учтена и вступит в силу).
[Оконный сторожевой таймер WWDG]
Оконный сторожевой таймер используется для того, чтобы обнаружить незапланированное поведение программы в реальном времени. Обычно такое происходит из-за внешних помех или непредвиденных логических условий, что приводит к отказу в нормальной последовательности выполнения кода программы приложения. Схема сторожевого таймера WWDG генерирует сброс MCU по истечении запрограммированного периода времени, если программа не обновит значение считающего вниз счетчика до того, как бит T6 очистится. Сброс MCU также генерируется, если 7-битное значение счетчика (в регистре управления) обновится до того, как счетчик достигнет значения регистра окна. Таким образом эти 2 условия сброса обеспечивают необходимость обновления счетчика в строго определенном, ограниченном окне времени.
Основные функции WWDG:
• Программируемый свободно считающий вниз счетчик • Сброс (если сторожевой таймер активирован), когда считающий вниз счетчик станет меньше 0x40 • Сброс (если сторожевой таймер активирован), когда считающий вниз счетчик был перезагружен вне установленного окна (см. рис. 215) • Генерация прерывания EWI (Early Wakeup Interrupt), если оно разрешено и сторожевой таймер активирован, когда считающий вниз счетчик становится равным 0x40
Если сторожевой таймер активирован (установлен бит WDGA в регистре WWDG_CR), то будет инициирован сброс, когда 7-битный считающий вниз счетчик (биты T[6:0] регистра WWDG_CR) перейдет от значения 0x40 к значению 0x3F (бит T6 очистится). Если программа перезагрузит счетчик, когда он больше значения, сохраненного в регистре окна, то также генерируется сброс.
Программа приложения во время своего нормального функционирования должна записывать регистр WWDG_CR в регулярные интервалы времени, чтобы предотвратить сброс MCU. Эта операция записи должна происходить только когда значение счетчика меньше, чем значение в регистре окна. Значение, сохраненное в регистре WWDG_CR, должно быть в интервале между 0xFF и 0xC0.
Разрешение сторожевого таймера. После сброса сторожевой таймер всегда запрещен. Он разрешается установкой бита WDGA в регистре WWDG_CR, после чего сторожевой таймер не может быть запрещен, кроме как через сброс.
Управление счетчиком. Счетчик свободно считает вниз, даже когда сторожевой таймер запрещен. Когда сторожевой таймер разрешен, бит T6 должен быть установлен, чтобы предотвратить немедленный сброс.
Биты T[5:0] содержат количество инкрементов, которые представляют задержку времени перед тем, как сторожевой таймер сгенерирует сброс. Время меняется между минимальным и максимальным значением из-за неизвестного состояния прескалера, когда записывается регистр WWDG_CR (см. рис. 215). Регистр конфигурации (WWDG_CFR) содержит верхний предел окна: чтобы предотвратить сброс, счетчик должен быть перезагружен, когда его значение меньше, чем значение регистра окна, и при этом больше, чем 0x3F. Рис. 215 описывает работу окна сторожевого таймера.
Примечание: бит T6 можно использовать для генерации программного сброса (для этого надо установить бит WDGA и очистить бит T6, либо подождать, когда он сам очистится).
Функция прерывания оконного сторожевого таймера. Можно использовать прерывание The Early Wakeup Interrupt (EWI), если перед выполнением реального сброса необходимо выполнить какие-нибудь предварительные операции (наподобие очистки или записи информации в лог). Прерывание EWI разрешается установкой бита EWI в регистре WWDG_CFR. Когда считающий вниз счетчик достигает значения 0x40, генерируется прерывание EWI, и соответствующая подпрограмма обработки прерывания (ISR) может использоваться для выполнения необходимых специальных действий (таких как например обмен данными или запись данных в лог) перед тем, как устройство будет сброшен.
В некоторых приложениях прерывание EWI может использоваться для управления программной проверки системы и/или корректного восстановления системы без генерации сброса. В этом случае соответствующий обработчик ISR должен перезагрузить счетчик WWDG, чтобы не произошел сброс WWDG, затем выполнить необходимые действия.
Прерывание EWI очищается записью 0 в бит EWIF регистра WWDG_SR.
Примечание: когда прерывание EWI не может быть обработано, например из-за блокировки системы в более высокоприоритетной задаче, то иногда будет генерироваться сброс WWDG.
Как программировать значение таймаута WWDG. Предупреждение: когда записывается регистр WWDG_CR, всегда записывайте 1 в бит T6, чтобы избежать немедленного сброса.
Рис. 215. Диаграмма времени работы оконного сторожевого таймера.
Формула для вычисления значения таймаута WWDG (в миллисекундах):
Таблица 109. Минимальные и максимальные значения таймаута на 30 МГц (fPCLK1).
Прескалер
WDGTB
Min таймаут (мкс) T[5:0]=0x00
Max таймаут (мс) T[5:0]=0x3F
1
0
136.53
8.74
2
1
273.07
17.48
4
2
546.13
34.95
8
3
1092.27
69.91
Режим отладки. Когда микроконтроллер STM32 входит в режим отладки (debug mode, ядро Cortex®-M4 с блоком FPU остановлено), счетчик WWDG либо продолжает свой счет, либо останавливается, в зависимости от бита конфигурации DBG_WWDG_STOP в модуле DBG. Для получения дополнительной информации см. секцию 38.16.2 "Debug support for timers, watchdog, bxCAN and I2C" руководства [1].
Регистры WWDG. К регистрам можно обращаться как к половинкам слов (16 бит) или как к полным словам (32 бита). Смещение указано относительно базового адреса. Например, для микроконтроллера STM32F429 базовый адрес равен 0x40002C00 (см. определение IWDG_BASE в заголовочном файле stm32f429xx.h библиотеки CMSIS).
В обозначениях бит используются аббревиатуры r, w, rw, rs, rc_w0, что означает следующее:
r доступ к биту возможен только для чтения (Read) w доступ к биту возможен только для записи (Write) rw доступ к биту возможен и для чтения, и для записи rs read/set, программа может прочитать и установить этот бит. Запись 0 в бит не оказывает никакого влияния на значение бита rc_w0 read/clear, программа может прочитать и сбросить этот бит. Запись 1 в бит не оказывает никакого влияния на значение бита
Биты 31:8 зарезервированы и должны сохраняться в состоянии сброса (все нули).
WDGA (бит 7) WatchDoG Activation, активация сторожевого таймера при записи лог. 1. Этот бит устанавливается программой, и он может сброситься только аппаратно после сброса. Когда WDGA = 1, сторожевой таймер может генерировать сброс.
T[6:0] (биты 6:0) 7-битное значение счетчика (от старшего бита MSB к младшему биту LSB). Эти биты содержат значение счетчика сторожевого таймера. Он декрементируется каждые (4096 x 2WDGTB[1:0]) тактов PCLK1. Сброс генерируется, когда счетчик переваливает от значения 0x40 к значению 0x3F (когда бит T6 очищается).
Биты 31:10 зарезервированы и должны сохраняться в состоянии сброса (все нули).
EWI (бит 9) Early Wakeup Interrupt. Когда этот бит установлен, произойдет прерывание всякий раз, когда счетчик достигнет значения 0x40. Это прерывание очищается только аппаратурой после сброса.
WDGTB[1:0] (биты 8:7) база времени сторожевого таймера, определяемая прескалером. Она может быть изменена следующим образом:
00: частота счетчика равна (PCLK1 / 4096) / 1 01: частота счетчика равна (PCLK1 / 4096) / 2 10: частота счетчика равна (PCLK1 / 4096) / 4 11: частота счетчика равна (PCLK1 / 4096) / 8
W[6:0] (биты 6:0) 7-битное значение окна времени, которое сравнивается со значением считающего вниз счетчика.
Биты 31:1 зарезервированы и должны сохраняться в состоянии сброса (все нули).
EWIF (бит 0) Early Wakeup Interrupt Flag. Этот бит установится аппаратно, когда значение счетчика достигнет 0x40. Бит может быть очищен программой путем записи в него лог. 0, запись лог. 1 не дает никакого эффекта. Этот бит также установится, если прерывание не было разрешено.