STM Урок 138. Independent watchdog (IWDG). Часть 1



В данном занятии мы познакомимся со сторожевым таймером (Watchdog timer).

Watchdog Timer (WDT) — это сторожевой таймер (а если перевести дословно, «сторожевой пёс»), который представляет собой аппаратно-реализованную схему контроля над зависанием системы. Это таймер, который периодически сбрасывается контролируемой системой. Если вдруг сброса не произошло за определённый интервал времени после предыдущего сброса данного таймера, то происходит принудительная перезагрузка системы (в нашем случае микроконтроллера).

В каких случаях мы применяем сторожевой таймер?

Например, мы ждём ответа от какой-нибудь шины (например I2C или ещё какой-то) в виде отслеживания состояния определённого бита регистра. И вдруг произойдёт кратковременное отсоединение провода этой шины. После этого скорей всего произойдёт зависание программы, так как в шине будет сбой, и даже если что-то после и придёт от присоединённого узла, то мы вряд ли уже это отследим изменением состояния бита. Желательно, чтобы после какого-то таймаута система перезагрузилась. Тут-то и приходит нам на помощь WDT, который установлен на определённый интервал. Команду на перезагрузку сторожевого таймера мы расположим в нашем коде после того, как мы дождёмся отклика от шины. А если мы так его и не дождёмся, то мы не дойдём до команды перезагрузки WDT и через заветный интервал времени система будет перезагружена. После этого произойдёт заново инициализация шины и всё будет опять работать нормально.

Понятно, что данная ситуация подходит только для случая, когда нам приходится не слишком долго ждать отклика от устройств, то есть именно тогда, когда у нас существует какой-то непрерывный процесс, в котором есть возможность ситуации сбоя. Таких примеров можно придумать много, поэтому Watchdog Timer очень много где применяется.

При работе со сторожевым таймером в нашем коде мы не будем напрямую работать с его регистрами, так как там ещё надо проделывать очень много различных подготовительных мероприятий. Для этого мы воспользуемся библиотекой HAL и проектогенератором Cube MX, которыми мы, впрочем, пользуемся всегда, и процесс кодинга очень сильно упростится. Но тем не менее о том, как именно устроен сторожевой таймер в контроллере STM32, а в частности в контроллере STM32F103, который расположен в очень недорогой отладочной плате и которым мы и будем сегодня пользоваться, мы всё же поговорим.

Сторожевой таймер в контроллере STM32F103 существует двух видов.

Independent watchdog (IWDG) — это независимый сторожевой таймер, который считает сверху вниз до нуля, начиная со значения, которое мы в нем установим. Как только счетчик дойдёт до нуля, то от сторожевого таймера поступит сигнал сброса, который заставит систему перезагрузиться. Но чтобы этого не произошло, мы должны заблаговременно перезагрузить IWDG или восстановить регистр, внеся заново в него требуемое число и тогда таймер начнёт снова обратный отсчёт.

Window watchdog (WWDG) — оконный сторожевой таймер, который работает подобным образом, только у него есть две границы — нижняя и верхняя, и сброс таймера должен произойти между данными границами, то есть таймер должен сброситься тоже обязательно до окончания полного интервала, но также и не раньше положенного срока, определяемого границей. Данный таймер мы будем изучать отдельно в другом уроке.

А пока IWDG.

Посмотрим его блок-схему

 

 

Из диаграммы мы видим, что тактируется таймер от отдельного низкоскоростного источника тактовых сигналов LSI (low-speed clock), от которого тактовые сигналы поступают в 8-битный предделитель, коэффициент которого устанавливается с помощью регистра IWDG_PR. В регистр IWDG_PLR мы заносим значение, от которого таймер при старте начнёт обратный отсчёт. Также существует регистр статуса IWDG_SR, в котором в момент изменения значения в регистре предделителя IWDG_PR, а также в момент занесения или обновления значения в регистре IWDG_PLR устанавливается соответствующий бит. Предварительно в ключевой регистр IWDG_KR для доступа к данным операциям изменений мы заносим определённое ключевое число. После того, как 12-битный обратный счётчик (downcounter) досчитает до 0, IWDG выдаст на своём выходе сигнал на перезагрузку системы.

Чтобы перезагрузка системы не произошла, мы должны своевременно подать команду на перезагрузку счётчика, чтобы он заново начал обратный отсчёт. Тем самым и обеспечивается контроль над зависанием программы в определённых точках, где такое возможно. Если мы не перезагрузим IWDG вовремя, это будет означать, что программа зависла и система перезагрузится.

Теперь подробнее рассмотрим регистры сторожевого таймера IWDG, хотя напрямую, если мы используем библиотеку HAL, мы ими не пользуемся.

 

 

Первый регистр — регистр доступа или ключевой

 

 

Старшие 16 бит не используются и зарезервированы.

Младшие 16 байт используются только на запись и в них заносится ключевое число.

Число 0xAAAA заносится для того, чтобы перезагрузить счётчик.

Число 0x5555 в данный регистр заносится для доступа к регистрам IWDG_PR и IWDG_PLR.

Число 0xCCCC в данный регистр записывается для того, чтобы таймер стартовал и его счётчик начал обратный отсчёт.

Число 0x0000 мы заносим для того, чтобы запретить доступ к регистрам IWDG_PR и IWDG_PLR.

Следующий регистр — регистр предделителя IWDG_PR

 

 

В младшие три бита заносятся биты, отвечающие за коэффициент деления частоты, остальные биты зарезервированы.

Посмотрим таблицу соответствия значения данных битов и коэффициента, который мы хотим настроить

 

 

Следующий регистр — IWDG_PLR

 

 

В данный 12-битный регистр (биты 11:0) заносится число, с которого впоследствии начинается обратный отсчёт.

Чтобы записать число в данные биты, надо получить доступ с помощью ключевого значения 0x5555, которое должно быть предварительно занесено в регистр IWDG_KR.

Также перед записью нового числа в регистр IWDG_PLR мы должны убедиться, что биты в статусном регистре IWDG_SR сброшены.

Следующий регистр — IWDG_SR или регистр статуса

 

 

Здесь активных битов только два.

Бит RVU (Watchdog counter reload value update).

Данный бит устанавливается, когда происходит обновление числа, с которого начинается счёт. Установка и сброс происходят только аппаратно.

Бит PVU (Watchdog prescaler value update).

Данный бит устанавливается, когда происходит изменение делителя в регистре IWDG_PR.

Теперь, думаю, стало немного понятнее.

Схема нашего урока состоит из недорого отладочной платы на контроллере STM32F103, установленной на макетной плате. К данной плате подведена тактовая кнопка к выводу PA1, а другой стороной кнопка подключена к общему проводу, также подключена светодиодная планка. состоящая из 10 светодиодов к выводам PA2:PA7, PB0, PB1, PB10 и PB11, так как данные ножки расположены подряд на отладочной плате. С другой стороны планки светодиоды подключены каждый через токоограничивающий резистор к общему проводу

 

 

Теперь можно смело приступить к проекту, который мы сегодня создадим с нуля.

 

 

Запустим проектогенератор Cube MX, создадим новый проект, выбрав наш контроллер

 

 

Включим тактирование

 

 

Включим отладку

 

 

Затем включим независимый сторожевой таймер (IWDG)

 

 

Включим таймер TIM2

 

 

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

 

 

Включим ножки, к которым подключены светодиоды, на выход

 

 

Перейдём в Clock Configuration и произведём там следующие настройки

 

 

В Configuration в настройках GPIO на ножке PA1 включим срабатывание по спаду, а также подтянем с неё резистор к питанию

 

 

В настройках NVIC включим внешние прерывания на ножке. Если будет установлена галка на только включенные прерывания, то снимем её предварительно, иначе мы не увидим наших прерываний

 

 

Зайдём в настройки таймера TIM2 и настроим также и его с тем расчётом, чтобы он генерировал прерывания примерно раз в секунду

 

 

Включим у таймера прерывания

 

 

Далее мы должны настроить наш сторожевой таймер IWDG.

Так как мы заведомо знаем, что IWDG тактируется от отдельного источника импульсов LSI частотой 40 килогерц, то настроить его будет несложно.

Установим в сторожевом таймере следующие настройки

 

 

Теперь посчитаем. Разделим на это всё значение частоты тактирования 40000, получим примерно 0,136. Это и будет значение частоты срабатывания таймера. Если мы найдём обратное число от данного значения, то есть на него поделим единицу, то получим приблизительно 7,36. Это уже будет значение интервала в секундах от пуска сторожевого таймера до того, как он перезагрузит систему, если его конечно не перезагрузить заблаговременно.

Сохраним настройки, а затем произведём настройки нашего проекта, который мы собираемся генерировать

 

 

Сохраним проект, сгенерируем проект для System Workbench, откроем его там, зайдём в настройки, установим уровень оптимизации в 1 и удалим отладочные настройки при их наличии.

Попробуем собрать проект. Если всё нормально собралось, то продолжим.

В следующей части урока мы напишем исходный код, в котором и закрепим на практике полученные знания по работе с таймером IWDG.

 

 

Предыдущий урок Программирование МК STM32 Следующая часть

 

 

Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6

Программатор недорогой можно купить здесь ST-Link V2

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM Independent watchdog IWDG

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*