[nRF52] 5. Watch dog timer & overwrite error handler

Dongsik·2022년 4월 21일
0

목적

  • 코딩의 신이 아니기 때문에 예상치 못한 상황을 대비하고자 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 에 대한 디버깅하는 방법을 잘 설명했다. 하지만 어렵다. (어셈블리어 공부를 먼저 좀 해야겠다...)

profile
There is a plenty of room at the bottom.

0개의 댓글