2013-02-07 24 views
14

Dopo aver spostato del codice incorporato in FreeRTOS, mi rimane un interessante dilemma sul cane da guardia. Il timer watchdog è un must per la nostra applicazione. Usare FreeRTOS è stato un grande vantaggio anche per noi. Quando l'applicazione era più single-tasked, alimentava il watchdog in punti tempestivi nel suo flusso logico, in modo che potessimo essere sicuri che l'attività stesse facendo progressi logici in modo tempestivo.Strategia per alimentare un cane da guardia in un ambiente multitask

Con più attività, tuttavia, non è facile. Un compito potrebbe essere legato per qualche motivo, non facendo progressi, ma un altro sta facendo bene e facendo progressi sufficienti per mantenere felicemente il cane da guardia.

Un pensiero era quello di avviare un'attività separata esclusivamente per alimentare il cane da guardia, e quindi utilizzare alcuni contatori che le altre attività aumentano regolarmente, quando l'attività del cane da guardia fa tic tac, farebbe in modo che tutti i contatori sembrino come i progressi fatti su tutte le altre attività, e se è così, andare avanti e dare da mangiare al cane da guardia.

Sono curioso di sapere cosa hanno fatto gli altri in situazioni come questa?

+4

Abbiamo fatto più o meno quello che hai detto. C'è un kicker e le attività con periodi noti si verificano con il kicker. Se queste attività non vengono eseguite in tempo, anche il kicker non viene eseguito. Il kicker dovrebbe essere il thread con la priorità più bassa nel sistema, quindi se il sistema non ha il tempo di arrivare al kicker, il dispositivo si resetterà. (Questo ti dà protezione anche sul kicker stesso.) Sono occupato ora, ma cercherò di mettere insieme una risposta più lunga insieme. – Ross

+0

Mi sembra di ricordare una domanda simile nell'ultimo mese o giù di lì, certamente con il tag incorporato. – Dan

risposta

7

Un'attività di controllo che monitora lo stato di tutte le altre attività è una buona soluzione. Ma invece di un contatore, considera l'utilizzo di un flag di stato per ogni attività. Il flag di stato dovrebbe avere tre possibili valori: UNKNOWN, ALIVE e ASLEEP. Quando viene eseguito un task periodico, imposta flag su ALIVE. Le attività che bloccano un evento asincrono dovrebbero impostare il loro flag su ASLEEP prima che si blocchino e ALIVE durante l'esecuzione. Quando l'attività del monitor watchdog è in esecuzione, dovrebbe dare un calcio al watchdog se ogni attività è ALIVE o ASLEEP. Quindi l'attività del monitor watchdog dovrebbe impostare tutti i flag ALIVE su UNKNOWN. (I flag ASLEEP devono rimanere ASLEEP.) Le attività con il flag UNKNOWN devono essere eseguite e impostare nuovamente i loro flag su ALIVE o ASLEEP prima che l'attività di monitoraggio esegua nuovamente il controllo sul watchdog.

vedere la sezione "multitasking" di questo articolo per ulteriori informazioni: http://www.embedded.com/design/debug-and-optimization/4402288/Watchdog-Timers

2

Questo è davvero un grande problema con i timer del watchdog.

Le mie schede hanno un LED su una linea GPIO, quindi lo faccio lampeggiare in un ciclo while/sleep, (750ms on, 250ms off), in un thread prioritario prossimo al più basso, (il più basso è thread inattivo che solo entra in modalità bassa potenza in un ciclo). Ho inserito un feed wdog nel thread flash LED.

Questo aiuta con arresti anomali completi e thread con priorità più alta del loop CPU, ma non aiuta se il sistema si blocca. Fortunatamente, i miei progetti di passaggio dei messaggi non si bloccano, (beh, non spesso, comunque :).

2

Non dimenticare di gestire possibili situazioni in cui vengono cancellati i compiti, o dormiente per lunghi periodi di tempo. Se tali attività sono state precedentemente verificate con un'attività di watchdog, devono anche avere un meccanismo di 'check out'.

In altre parole, l'elenco delle attività per le quali è responsabile un'attività di watchdog deve essere dinamico e deve essere organizzato in modo che alcuni codici non possano facilmente eliminare l'attività dall'elenco.

lo so, più facile a dirsi che a farsi ...

0

ho progettare la soluzione utilizzando i timer FreeRTOS:

  1. SystemSupervisor SW Timer che alimentano l'HW WD. FreeRTOS Failure causa il reset.
  2. Ogni attività crea il "proprio" timer SW con la funzione SystemReset.
  3. Ogni attività responsabile di "manualmente" ricarica il suo timer prima che sia scaduto.
  4. funzione SystemReset salva i dati prima di commettere un suiside

Ecco alcuni listing pseudo-codice:

//--------------------------------- 
// 
// System WD 
// 
void WD_init(void) 
{ 
HW_WD_Init(); 
    // Read Saved Failure data, Send to Monitor 
    // Create Monitor timer 
    xTimerCreate( "System WD",  // Name 
        HW_WD_INTERVAL/2, // Reload value 
        TRUE,    // Auto Reload 
        0,     // Timed ID (Data per timer) 
        SYS_WD_Feed); 
} 
void SYS_WD_Feed(void) 
{ 
    HW_WD_Feed(); 
} 

//------------------------- 
// Tasks WD 
// 
WD_Handler WD_Create() 
{ 
    return xTimerCreate( "",     // Name 
          100,    // Dummy Reload value 
          FALSE,    // Auto Reload 
          pxCurrentTCB,  // Timed ID (Data per timer) 
          Task_WD_Reset); 
} 

Task_WD_Reset(pxTimer) 
{ 
    TaskHandler_t th = pvTimerGetTimerID(pxTimer) 
    // Save Task Name and Status 
    // Reset 
} 

Task_WD_Feed(WD_Handler, ms) 
{ 
    xTimerChangePeriod(WD_Handler, ms/portTICK_PERIOD_MS, 100); 
} 
Problemi correlati