목적
- 코딩의 신이 아니기 때문에 예상치 못한 상황을 대비하고자 WDT를 적용해야한다.
- Reset caues 확인과 WDT reset 동작 테스트도 하자.
- WDT reset 전에 log 를 저장해보자.
- 프로그램이 리셋되게 만든 코드 라인을 저장하고 싶기 때문에 에러 핸들에 대한 강화를 뜬금없이 진행하겠다!!
Git
https://github.com/tlaehdtlr/nrf52_ble_base
- 17 commit : [Feat] Add reset reason
- 18 commit : [Feat] Add WDT and wdt command for test
- 19 commit : [Feat] Store log before wdt reset and overwrite app_error_fault_handler
1. Reset reason 구하기
1-1. base_debug.c 만들기
상품화를 진행하며 느낀 점은 HW 개발자, 품질팀, 고객들은 기기가 오작동을 한다고 생각하면 앞뒤 빼고 마지막에 보이는 현상만 말한다
예기치 못한 상황을 복구하고 어떤 이유인지를 MMI로 보여주거나 log를 flash 에 저장한다면 field 에 나가서도 대처하기 좋을 것이라고 생각한다. 이를 위해 만들어놓자!
1-2. 구현
nRF52833_PS_v1.3.pdf 의 RESETREAS 레지스터를 참고하자
4개의 경우만 제대로 print 찍어주겠다(귀찮으니까)
1-3. 결과

2. WDT 적용
2-1. 구상
Watchdog timer 를 활성화시키는 것은 쉽다. 다만 단순하게 timer feed, reset 만 하기보다 나름의 고려사항들을 정리하고 설계하자.
어떤 에러를 고려하고 어떻게 feed 를 해줄 것이냐, reset 걸리기 직전에는 어떤 행동을 해줄 것이냐를 고민해보자.
(참고 4-1을 보며 좋은 구조에 대해 많이 생각해 볼 수 있었다.)
1) Feed와 reset
- Feed 하는 interval은 time out 걸리기 전에 2번 할 수 있도록 할 것이다. (ex. feed 2s, timeout 5s)
- Feed interval 은 RTC 기반인 app timer 로 맞추고 flag 를 풀어주는 개념 (High priority)
- Infinite loop 에서 flag 를 체크하여 feed 해주기 (Idle priority)
- 유선 통신 등 필수 기능에 대한 미작동시, error handler 에 의해 wdt reset 걸리도록 함
2) Jump to address
- Bootloader, softdevice 등을 사용하는데 wdt를 활성화시키고 feed를 application code에서만 해도 문제 없는지 확인
3) Reset 직전
- reset 걸리기 직전에 wdt event handler 가 불리고 2번의 32.768kHz cycle 여유가 있다.
- 직전에 다른 행위를 하기에는 너무 짧은 시간이고, 로그를 저장하는 것만 할 수 있겠다.
2-2. 구현
1) base_wdt.c 생성
- WDT init
- WDT feed timer (for main loop to know flag)
2) main.c
- infinite loop 에서 flag 체크 후, feed 함수 호출
3) noinit RAM 활용
- gcc 컴파일러를 사용한다면 밑에처럼 쓰면 된다.

- WDT reset 이 걸리는 라인을 기록하기에는 내 능력이 아직 부족했다... call stack이나 program counter를 trace(unwind?) 하는 방법을 열심히 강구했지만 실패했다.(어셈블리어를 잘 사용한다면 될 거 같은데...) 그래서 ToDo 로 남기겠다!
- 여튼 유의미한 정보를 저장할 게 없어서 wdt_event_handler 에서는 결국...
이거만 했다 ㅎ
2-3. 결과

3. Error 핸들링
3-1. Overwrite app_error_fault_handler
- APP_ERROR_CHECK 함수의 경우 weak 함수인 app_error_fault_handler 호출한다.
- 이 녀석을 overwrite 하여 APP_ERROR_CHECK 의 에러 라인을 non_init RAM 에다가 저장해보겠다.


- app_error_save_and_stop 함수를 참고하여 app_error_fault_handler 를 커스텀하였다.
- APP_ERROR_CHECK 에 의한 리셋은 soft reset 이 되도록 하였다. WDT 리셋 걸리는 시간이 아까워서다... ㅎ
- 기기가 자꾸 리셋되는 것이 안 되는 경우에도 여기를 커스텀해서 잘 쓰면 되겠다.
3-2. 결과
아래와 같이 soft reset 이 걸리고 어디서 잘못됐는지 친절히 알려준다. 굉장히 뿌듯하다.

4. 참고
memory usage
Flash : (219.2 -> 220.5) +1.3KB
RAM : (30.1 -> 30.2) +0.1KB

4-1) WDT를 임베디드 시스템에 어떻게 적용할지에 대한 글 (생각할 거리가 많다. 정말 유용하다.)
4-2) Fault 에 대한 디버깅하는 방법을 잘 설명했다. 하지만 어렵다. (어셈블리어 공부를 먼저 좀 해야겠다...)