Флаги причины сброса
Устройство иногда перезагружается само, и важно понять почему: просело питание, сработал сторожевой таймер или кто-то нажал кнопку. Микроконтроллер запоминает причину последнего сброса в специальных флагах, которые переживают сам сброс.
Обновлено Редакция GAW
Флаги причины сброса (reset flags) — биты в регистре состояния микроконтроллера, которые аппаратно устанавливаются при сбросе от определённого источника и сохраняются после него. Программа читает их в начале работы и узнаёт, отчего произошёл перезапуск: включили питание, нажали кнопку RESET, сработал сторожевой таймер, просело питание или программа сама запросила сброс.
STM32: регистр RCC_CSR
| Флаг | Причина (RM0008, RM0090) |
|---|---|
| PORRSTF | сброс при включении питания или выключении (POR/PDR) |
| BORRSTF | только STM32F4: POR/PDR или детектор пониженного питания BOR |
| PINRSTF | низкий уровень на выводе NRST |
| IWDGRSTF | независимый сторожевой таймер IWDG |
| WWDGRSTF | оконный сторожевой таймер WWDG |
| SFTRSTF | программный сброс через бит SYSRESETREQ ядра |
| LPWRRSTF | сброс вместо входа в Stop или Standby, если так настроены байты конфигурации |
Флаги очищаются записью 1 в бит RMVF того же регистра, а сам системный сброс их не трогает — стирает только сброс по питанию. Отсюда тонкость: после включения у STM32F103 регистр равен 0x0C00 0000, то есть стоят и PORRSTF, и PINRSTF, потому что сброс по питанию тоже действует через вывод NRST и держит его в нуле (RM0008, разд. 7.1.2). Поэтому PORRSTF проверяют первым. Как вызвать программный сброс, показано в ответе «Как программно перезагрузить микроконтроллер».
AVR: регистр MCUSR
У ATmega328P флагов четыре: PORF — включение питания, EXTRF — внешний сброс по выводу RESET, BORF — детектор пониженного питания, WDRF — сторожевой таймер. Флаги WDRF, BORF и EXTRF сбрасываются при включении питания или записью нуля, PORF — только записью нуля (DS40002061B, разд. 11.9.1). Microchip советует прочитать и очистить MCUSR как можно раньше в программе. Если устройство перезапускается сторожевым таймером, флаг WDRF к тому же держит таймер включённым: бит WDE принудительно равен единице, пока WDRF не сброшен (DS40002061B, разд. 11.9.2).
Как пользоваться
Типичный приём — в самом начале программы сохранить значение регистра в переменную, очистить флаги и затем записать причину в журнал или передать по UART. Так отличают зависание, после которого сработал сторож (таймаут считает калькулятор сторожевого таймера STM32), от провалов питания.
Не путать с флагами состояния процессора — переноса, переполнения и т. п. — и с вектором сброса: вектор задаёт, откуда начнётся выполнение, а флаги — почему.
Частые вопросы
Как узнать причину сброса STM32?
Прочитать регистр RCC_CSR в начале программы и проверить флаги: PORRSTF — включение питания, PINRSTF — вывод NRST, IWDGRSTF и WWDGRSTF — сторожевые таймеры, SFTRSTF — программный сброс, LPWRRSTF — сброс при входе в Stop или Standby. Потом записать 1 в бит RMVF, чтобы к следующему сбросу флаги были чистыми.
Почему после включения питания у STM32 стоит и флаг сброса от вывода?
Значение RCC_CSR после сброса по питанию у STM32F103 — 0x0C00 0000, то есть стоят оба флага, PORRSTF и PINRSTF; у STM32F407 — 0x0E00 0000, ещё и BORRSTF (RM0008, разд. 7.3.10; RM0090, разд. 7.3.21). Поэтому сначала проверяют PORRSTF и только если его нет — остальные флаги.
Зачем стирать флаги после чтения?
Флаги накапливаются: системный сброс их не очищает. Если не стереть их битом RMVF у STM32 или записью нуля в MCUSR у AVR, после следующего сброса программа увидит и старую, и новую причину и не отличит одну от другой.
Источники
- STMicroelectronics. RM0008 Rev 21. Reference manual: STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx — разд. 7.1.1: источники системного сброса — вывод NRST, WWDG, IWDG, программный (SYSRESETREQ), сброс по режимам пониженного потребления; причину показывают флаги RCC_CSR; системный сброс не трогает флаги и резервный домен; разд. 7.1.2: сброс по питанию — POR/PDR и выход из Standby, импульс на NRST не короче 20 мкс; разд. 7.3.10: RCC_CSR — LPWRRSTF, WWDGRSTF, IWDGRSTF, SFTRSTF, PORRSTF, PINRSTF, все стираются записью RMVF; значение после сброса 0x0C00 0000, флаги сбрасываются только сбросом по питанию
- STMicroelectronics. RM0090 Rev 21 (June 2024). Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439 — разд. 7.3.21: RCC_CSR STM32F405/407 — те же флаги и BORRSTF (ставится при POR/PDR и BOR), сброс RMVF; значение после сброса 0x0E00 0000; разд. 7.1.2: сброс по питанию включает BOR
- Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B, 2020) — разд. 11.9.1: MCUSR — WDRF, BORF, EXTRF, PORF; WDRF, BORF и EXTRF сбрасываются сбросом при включении питания или записью нуля, PORF — только записью нуля; регистр советуют прочитать и очистить как можно раньше в программе; разд. 11.9.2: WDE принудительно установлен, пока установлен WDRF
Нашли ошибку?
Смотрите также
- Сторожевой таймерWatchdog: сброс МК при зависании программы
- Сброс при включении питанияВнутренний сброс до роста питания: пороги, скорость нарастания, примеры
- Детектор пониженного питанияBrown-out detector: сброс МК при просадке питания
- Как программно перезагрузить микроконтроллер?SYSRESETREQ на Cortex-M, сторожевой таймер на AVR
- Сторожевые таймеры STM32PR и RLR у IWDG, WDGTB, счётчик и окно у WWDG, разброс LSI, код