Перейти к содержанию

Флаги причины сброса

Устройство иногда перезагружается само, и важно понять почему: просело питание, сработал сторожевой таймер или кто-то нажал кнопку. Микроконтроллер запоминает причину последнего сброса в специальных флагах, которые переживают сам сброс.

Обновлено Редакция 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, после следующего сброса программа увидит и старую, и новую причину и не отличит одну от другой.

Источники

  1. 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, флаги сбрасываются только сбросом по питанию
  2. 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
  3. 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

Нашли ошибку?