티스토리 뷰
개요
원문 참고링크: https://www.codeproject.com/Articles/1012319/Arduino-Software-Reset
임베디드 시스템에도 오동작등 다양한 이유로 재부팅을 해야할 경우가 있다.
(Arduino 이지만) 참고 링크에서는 세 가지 방법을 소개하고 있으며,
그 중에서 추천하고 있는 Watchdog Reset 을 소개해본다.
TL;DR
아래 코드를 쓰시오.
#include <avr/wdt.h> void
softwareReset( uint8_t prescaller) { void setup() { // add setup code here...} void
loop() { // restart in 60 milliseconds |
Watchdog 프로세스
1) Watchdog 을 Enable 한다.
2) 이때 설정한 시간내에 Watchdog 을 reset (혹은 clear) 하지 않으면 Watchdog reset 이 걸린다.
이를 활용하여
1) Watchdog 을 Enable 한 다음
2) 무한루프를 돌려서 Watchdog reset 이 걸리게 강제하여 Software reset 을 하게 만든다.
TroubleShooting
Q. 이상하게 이렇게 reset 이 되고 나면 계속 reset 됨
- main() 에서 시작하자 마자 wdt_disable() 을 먹여도 안됨
A. 아래 공식 언급을 참고할 것
- WDT 는 reset 되고 나서도 살아있음. (except power on reset)
- 심지어는 15ms 내에 wdt_reset() 을 먹여주지 않으면 또 리셋이 됨
- 그래서 아예 main() 함수를 타기 전에 MCUSR 레지스터를 리셋해주고, wdt_disable() 해주어야 한다.
- 공식언급: https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__watchdog.html
Note that for newer devices (ATmega88 and newer, effectively any AVR that has the option to also generate interrupts), the watchdog timer remains active even after a system reset (except a power-on condition), using the fastest prescaler value (approximately 15 ms). It is therefore required to turn off the watchdog early during program startup, the datasheet recommends a sequence like the following: |
main() 함수보다 빠른 실행
어떻게 main() 함수의 실행 이전에 코드를 먹일 수 있는가?
디테일한 설명을 생략하면, 함수를 main() 함수 이전에 실행되는 영역에 두면 된다.
공식 링크: https://goo.gl/9ZG2xc
#include <stdint.h> #include <avr/wdt.h>
uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); void get_mcusr(void) \ __attribute__((naked)) \ __attribute__((section(".init3"))); void get_mcusr(void) { mcusr_mirror = MCUSR; MCUSR = 0; wdt_disable(); } int main(void) { //get_mcusr(); wdt_enable(WDTO_2S); ... while(1) { ... wdt_reset(); ... } } |
1) mcuser_mirror 변수는 .noinit 영역에 메모리를 할당한다. - 초기 부팅시 등등 다양한 상황에서도 지워지지 않게 해줌
2) get_mcusr() 함수는 .init3 영역에 써준다. - 이 영역에 써두면 부팅시에 자동으로 - main() 함수 이전에 실행이 되는 것이다.
→ 이제 언제든 mcusr_mirror 변수를 보면 리셋의 원인을 알 수 있다.
(주의) get_mcusr() 함수는 자동으로 실행된다. - main() 함수내에서 실행시키면 오동작한다. * 왼쪽 코드에서는 참고삼아 코멘트 처리 해두었다. * 참고링크: https://www.avrfreaks.net/forum/watch-dog-question
|
'embedded' 카테고리의 다른 글
Edit and Execute code in Raspberry Pi from Visual Studio Code in my computer (0) | 2019.03.20 |
---|---|
Embedded Project - Modularizing (0) | 2019.01.18 |
Atmel Studio, Atmel-ICD - debugWIRE 사용하기 (0) | 2018.12.27 |
ScriptCommunicator - Serial packet test (0) | 2018.12.20 |
Arduino - Memory and PROGMEM, F() macro (0) | 2018.09.28 |
- Total
- Today
- Yesterday
- 티스토리챌린지
- 오블완
- strange
- 2023
- golang
- github
- 잡학툰
- websocket
- Gin
- solid
- 독서
- ChatGPT
- 노션
- 인텔리제이
- 독서후기
- 체호프
- 영화
- bun
- go
- folklore
- notion
- 엉클 밥
- Bug
- clean agile
- 클린 애자일
- intellij
- 제이펍
- OpenAI
- API
- agile
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |