본문 바로가기
Hardware/MCU(Arduino,ESP8266)

ESP8266, Watchdog (wdt reset error)

by lovey25 2020. 12. 9.
반응형

Watchdog은 esp8266 시스템을 모니터링하는 도구로써 정해진 시간이 지나면 시스템을 리셋하는 기능을 합니다. 그래서 의도치 않은 에러가 발생하거나 무한루프에 빠져서 시스템 로직이 멈추게 되면 watchdog이 개입을 해서 esp8266 전체 시스템을 리부팅하게 됩니다. 반대로 말하면 시간이 오래 걸리는 로직을 수행할 때 시스템이 정상적으로 계속 작동하기 위해서는 watchdog이 발동하기 전에 watchdog timer(wdt)를 계속 리셋해주어야 합니다. 

ESP8266에는 두 가지 종류의 wahtchdog이 있는데 Software와 Hardware watchdog입니다. 

Software watchdog

Software watchdog은 다음과 같이 무한루프에 빠지게 되면 발동이 되는데요. 꼭 무한루프가 아니더라도 아무것도 하지 않고 대기하는 시간이 조금이라도 길어지면 바로 watchdog이 개입해서 리셋을 시켜버립니다.

while (true) {};

펌웨어에 위와 같은 무한루프를 포함해서 실행시켜보면 다음과 같이 반복적으로 리셋이 되는 모습을 확인할 수 있습니다.

여기서 "rst cause:2"라는 메시지가 표시되고 있는데요. Datasheet를 찾아보면 2번은 외부요인에 의한 리셋이라고 되어 있네요. 이게 Software watchdog에 의한 리셋인가 봅니다.

출처: "ESP8266 Reset Causes and Common Fatal Exception Causes"

하지만 다음 명령을 대기하는 등 사유로 의도적으로 상당 시간 동안 시스템이 멈추어야 하는 경우에는 watchdog이 개입을 하게 되면 시스템이 리셋이 되어서 정상적인 동작이 방해되는 상황이 발생할 수 있습니다. 이럴 때 wdt를 연장시켜서 watchdog의 개입을 늦춰줄 필요가 있는데요. 이럴 때는 다음의 명령을 이용해서 wdt를 지연시킬 수 있습니다. wdtFeed() 함수는 ESP 클래스(ESP.cpp)에 정의된 함수로 타이머를 지연시키는 역할을 한다고 하고 yield() 함수는 대기하는 동안 제어권을 백그라운드 함수에게 넘겨주는 일을 한다고 하는데 정확한 동작 로직은 이해하지 못했습니다. 그냥 그런 용도로 쓰는구나 정도로만 이해하고 넘어갔습니다. ;;

 ESP.wdtFeed();
 // OR
 yield();

그리고 software watchdog을 비활성화시켜서 아주 사용하지 않도록 할 수도 있는데요. ESP 클래스에 정의된 wdtDisable() 함수로 비활성화할 수 있습니다.

ESP.wdtDisable();

반대로 비활성화시킨 wdt를 다시 활성화시키기 위해서는 wdtEnable() 함수를 사용합니다.

ESP.wdtEnable(1000);    // millisecond timer

매개변수로는 밀리초단위의 정수를 입력해 주어야 하는데 wdt의 대기시간으로 설정됩니다.

Hardware watchdog

그러면 Hardware watchdog은 언제 개입을 할까요? 바로 software watchdog이 제기능을 못할 때 나서게 되는데요. 다음과 같이 software watchdog을 죽여놓고 의도적으로 무한루프에 빠지게 해 보면 hardware watchdog이 발동하는 것을 활일 할 수 있습니다. software 리셋보다는 조금 더 길게 기다리다가 리셋 메시지가 뜨네요.

ESP.wdtDisable();
while (true) {};

이번에는 "rst cause:4"으로 Hardware watchdog에 의한 리셋이란 걸 명확하게 알 수 있네요.

 

참고로 하드웨어 watchdog은 비활성화할 수 없다고 합니다.

 

끝!

반응형

댓글