nowornever

Watchdog task 워치독 본문

Study

Watchdog task 워치독

JohnnyKoo 2012. 2. 13. 09:16
오늘은 마이크로컨트롤러를 공부하면서 자주 나오는 watchdog task에 대해 알아보도록 하자. 

친절한 임베디드 시스템 개발 페이지에 따르면 다음과 같이 설명이 되어져 있어 퍼왔다.

출처:  http://recipes.egloos.com/5097718 
친절한 임베디드 새스템 개발자 되기 강좌
==============================================================================================
일반적인 Embedded System에는 Watch dog이라는 Timer Hardware가 존재해요. Watch dog Timer라는 건 모든 Task가 제 때 응답할 수 있는지를 Check해서 문제가 있을 경우에는 Hardware적으로 Target을 Reset 시키는 게 그 목적인 거죠. 좀 어렵나요. 한마디로 말해서 Embedded System에 올라와 있는 모든 Task가 문제 없이 돌아 가고 있는지 - 를 확인 한다는 건 대충은 Starvation이라는 경우를 말하는 데, Priority가 높은 녀석들이 계속 일을 해대서 Priority가 낮은 Task에게 순서가 잘 오지 못하는 상황을 일컫는 거에요 -, 또한 어떤 Resource에 대해서 Mutex를 잘못 걸어서 교착 상태에 빠졌다던가 해서 System이 Lock up이 되거나 하면 System을 다시 원상 복구 시켜야 되는데 그게 참 어려우니까, 간단하게 System을 Reset 시켜 버리는 거지요. 그 방법이라는 게 Hardware적인 Timer를 두고서 그 Timer가 Expire되면 (모래시계의 모래가 다 떨어지면) System을 Reset 시켜 버리는 거구요, Expire 되기 전에 (모래 시계가 다 떨어지기 전에) 모든 Task가 정상적으로 나 살아 있다는 Report를 받으면 Timer를 Reset (처음 값으로 설정)해서 다시 모래 시계가 떨어지도록 하는 System인거에요. 오호라. 간단하지요?
 
그러려면, 이런 Watch dog timer를 관리하는 Task가 하나 있으면 편하겠지요? 이 Task가 하는 일은 모든 Task가 제 때 살아 있다고 Report했는지 확인하고 제 때 Report 못한 녀석이 있으면 System을 Lock up 걸어 버리고, Watch dog timer가 Expire되도록 하는 게 임무인거에요.
 
자자, 그러면 Watch dog task를 어떤 식으로 구현하면 좋을까요? 첫 번째로는 모든 Task가 Timer Call Back을 등록해서 Watch dog task에게 나 살아 있다고 report 할 수 있도록 구성해야 겠지요.
여기에서 중요한 건 모든 Task마다 report해야 하는 시간이 같은 게 아니라, 적당하게 자기에게 맞는 시간을 정해 주는 게 중요해요. Priority가 높다고 해서 더 자주 Report하느냐, 그것도 아니고, Priority가 낮다고 해서 더 자주 Report하느냐 그것도 아니고. System을 만들다 보면 워낙 복잡하게 만들어서 Monitoring 자주 해줘야 하는 Task들이 있는데, 그런 관심 사병들 일 수록 Report 시간이 짧아야 해요. 그래야 어떤 녀석이 Lock up 자주 Lock up의 주범이 되는지 Debugging 하기도 좋겠지요.
 
그럼 Watch dog task 이외의 Task들이 주기적으로 Report하게 하려면 어떻게 해야 할까요.
 
void 다른모든_task ()
{
     set_timer (호출한 자기 자신, DOG_REPORT_SIG, 자기한테 알맞은 시간);
      wait_signal(DOG_REPORT_SIG)
      if (get_signal () == DOG_REPORT_SIG)
         {
           send_signal (Watchdog_task, 자기 자신); /* report to watch dog task */
           clr_signal (DOG_REPORT_SIG)
         }
}
 
자, 어때요? 이런 식으로 하면 Watch dog task 이외의 모든 Task는 주기적으로 일어나서 Watch dog task에게 "나, 살아있어~"라고 알려 줄 수 있겠지요?
 
그러면, Watch dog task는 어떻게 구현하면 좋을까요? Watch dog task도 역시나 주기적으로 일어나서 확인하면 되겠지요? 대신 중요한 건 Watch dog task는 다른 모든 task들이 어느 주기로 Report 해야 되는지를 꼭 알고 있어야 겠지요? Watch dog task는 주기적으로 일어나서 어떤 일을 하냐면,
 
void Watch_dog_task ()
{
     set_timer (호출한 자기 자신, WAKE_UP_SIG, 적당한 주기);
      wait_signal(WAKE_UP_SIG)
      if (get_signal () == WAKE_UP_SIG)
         {
             for (Task 개수)
              {
                    각 task의 모래 시계를 Watch dog이 일어나는 주기인 "적당한 주기" 만큼 씩  빼주고,
                    설마 이렇게 빼준 값이 0보다 작아져 버리면! 그 0보다 작아진 넘이 나쁜 넘!!!
                           Interrupt_lock()을 걸어버리고 While(1)을 걸어 버려서
                           Watch dog timer expire가 되어 Reset이 되게 만들어 버린다. 난 잔인해.
              }
           clr_signal (DOG_REPORT_SIG)
         }
}
 
뭐, 이런 셈인 거죠. 이렇게 해서 제 때 Report 못하는 녀석을 걸러 내는 역할 을 하죠. 생각보다 컨셉은 간단하죠. 자, 이렇게 해서 System이 Reset되면 정상화는 되서 좋겠지만, 우리 개발자의 입장에서는 그렇게 만드는 범인을 잡아 내야 하겠지요. 범인은 보통 지금 Report를 못한 Task가 문제인 경우도 있고, 그 Task보다 더 높은 Priority를 가진 Task가 범인 일 때도 많이 있어요. 더 높은 Priority를 가진 Task가 하도 오래 붙잡고 있으니까, 결국 Report를 못하는 녀석이 생기는 거죠 - 이런 게 앞에서 말한 Starvation이에요 -. 그런 거에요. Watch dog은 그런 측면에서 System을 Watch하고 있는 감시견 이라는 의미인 거죠 

 ========================================================================

'Study' 카테고리의 다른 글

패킷(packet)  (0) 2012.05.23
Flyback diode (freewheeling diode)  (0) 2012.02.16
MIT Open Courseware  (1) 2012.02.09
a distance from the origin to the plane  (0) 2012.02.09
AVR 게시판 오픈  (0) 2012.02.09