Usant el watchdog en un RTOS

Quan es treballa en un entorn amb un RTOS, cal estudiar bé com fer servir el watchdog. La primera pensada pot ser d’afegir les crides per alimentar el watchdog a cada una de les tasques com si fossin mini-aplicacions individuals. Aquesta aproximació, però, faria que el sistema mai es reiniciï encara que una tasca deixi e funcionar o tingui algun problema greu, ja que la resta de tasques seguirien alimentant-lo.

La solució més habitual és la de tenir una tasca dedicada a la tasca d’alimentar el watchdog i que rebi una mena d’OK de cada una de les tasques restants del sistema. D’aquesta forma, si una tasca deixa de funcionar, aquesta tasca dedicada ho detectarà i deixarà d’alimentar el watchdog provocant que el sistema es reiniciï

#define WATCHDOG_TASK1 0x01
#define WATCHDOG_TASK2 0x02

#define WATCHDOG_FULL (WATCHDOG_TASK1 |WATCHDOG_TASK2)

static uint8_t watchdog_list;
static SemaphoreHandle_t watchdog_mutex;

void watchdogTouch(uint8_t task) {
  xSemaphoreTake(watchdog_mutex, portMAX_DELAY);
  watchdog_list |= task;
  xSemaphoreGive(watchdog_mutex);
}

void watchdogClear() {
  xSemaphoreTake(watchdog_mutex, portMAX_DELAY);
  watchdog_list = 0;
  xSemaphoreGive(watchdog_mutex);
}

void watchdogTask(void *parameter) {
  ...
  WDOG_Init(&init);
  watchdog_mutex = xSemaphoreCreateMutex();

  while(1) {
    if (watchdog_list == WATCHDOG_FULL) {
      WDOG_Feed();
      watchdogClear();      
    } 

    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

El codi que es veu al llistat  proporciona la funció watchdogTouch() que és la que haurà de cridar les diferents tasques del sistema, cadascuna amb un paràmetre  WATCHDOG_TASK<N> diferent i únic (codi al repositori).

Com es pot veure a l’exemple, la variable local a la biblioteca watchdog_list emmagatzema l’estat de totes les tasques i s’hi accedeix a la funció watchdogTouch() que protegeix l’accés amb un mutex. La tasca watchdogTask() avalua aquesta variable d’estat i si tot ha anat correctament (totes les tasques han cridat la seva funció almenys un cop), alimenta el watchdog En cas contrari, la tasca no l’alimenta i acabarà per reiniciar el sistema.

A l’exemple aquesta tasca s’executa un cop cada segon, i el watchdog s’ha de configurar d’acord a aquest temps (un temps de watchdog de 2 segons seria l’adequat). La resta de tasques haurien de cridar la funció  watchdogTouch() amb un període de temps per curt (per exemple cada 500 mil·lisegons) per tal de que tot el sistema s’executi correctament.

Anuncis

Deixa un comentari

Fill in your details below or click an icon to log in:

WordPress.com Logo

Esteu comentant fent servir el compte WordPress.com. Log Out /  Canvia )

Google+ photo

Esteu comentant fent servir el compte Google+. Log Out /  Canvia )

Twitter picture

Esteu comentant fent servir el compte Twitter. Log Out /  Canvia )

Facebook photo

Esteu comentant fent servir el compte Facebook. Log Out /  Canvia )

S'està connectant a %s

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.