Gestione degli errori in macchine a stati multipli in sistemi embedded in C

1

Ho poche macchine a stati che girano "simultaneamente" in un super-ciclo.

do
{
  state_one();
  state_two();
  state_three();

  /* The point I want to deal with the error */

} while(1);

Ciascuna di queste macchine a stati potrebbe essere costituita da altre macchine a stati.

Sto cercando di capire come riuscirò a cogliere una situazione inaspettata e ad analizzarla direttamente al main.

Il che significa che l'errore dovrà passare attraverso tutti gli stati e che ogni stato deve affrontare questo errore. Ad esempio: il microcontrollore che sto utilizzando è un ATSAM4S Cortex-M4 e che si occupa dell'errore potrebbe essere:

  • Ripristino del sistema
  • Non reimpostare il timer del watchdog
  • Stampa un messaggio triste
  • Lampeggia un led sul tabellone
  • Scrivi qualcosa in una memoria esterna
  • Disabilita un alimentatore
  • Attiva una variabile
  • Esegui un'altra macchina a stati
  • Forza una macchina a stati per cambiarne lo stato
  • Ignora l'errore

Le mie macchine a stati sono implementate con il metodo puntatore a funzione

typedef struct My_state_machine_t
{
   uint32_t (*run)(struct My_state_machine_t * const This_state_p);
   uint64_t entry_time_ms; 
}My_state_machine_t;

state_one () potrebbe contenere:

My_state_machine_t my_state = {
    .run = first_state;
    };

uint32_t state_one(void)
{
   if (my_state.run != NULL)
   {
      my_state.run(&my_state);
   }
   return 0;
}

uint32_t first_state(My_state_machine_t * const This_state_p)
{
   /* run some functions */

   // Now we are jumping to next state
   This_state_p->run = &this_is_the_next_state;
   This_state_p->entry_time_ms = system_get_ms();
   return 0;
}

Inoltre, ogni stato darà un diverso tipo di errore. Diversi tipi di errore significano azioni diverse. Inoltre, alcuni errori potrebbero essere comuni tra gli stati e in questo caso il "gestore degli errori" dovrà prendere le stesse decisioni o simili (ad esempio, il ripristino del sistema).

    
posta MrBit 08.03.2018 - 00:21
fonte

1 risposta

1

Un campo di bit variabile globale può tornare utile. Ogni stato ha un insieme di bit definiti all'interno del campo di bit, ognuno dei quali deve fornire uno stato.

Ad esempio, la macchina di stato uno può impostare (e cancellare) i bit chiamati SM1_BAD_FOO, SM1_BAD_BAR, SM1_BAD_BAZ. Nella macchina di stato 1, se "BAD FOO" si verifica, imposta il bit, altrimenti cancella il bit. Lo stesso vale per altri eventi "BAD" e altri stati.

Quindi nel tuo ciclo principale, controlli se il campo di bit globale è diverso da zero. Se lo è, è successo qualcosa di brutto, e ha bisogno di gestirlo.

Puoi anche fare in modo che ogni stato possa solo SET il bit (non chiaro) e solo il loop principale può cancellare, in questo modo se ci sono influenze esterne sul "BAD" che vanno via, il loop principale potrebbe avere più visibilità che ogni macchina a stati.

FYI, questo tipo di soluzione è abbastanza comune nei sistemi embedded.

    
risposta data 11.04.2018 - 19:22
fonte

Leggi altre domande sui tag