NOWAE

Our ideas, your fun!

WETS: un semplice scheduler event-driven



Ed eccoci di nuovo qui... scusate la lunga assenza!

In questo articolo torniamo a parlare di firmware, ed in particolare di librerie utili nel quotidiano.
Nei miei dodici anni di attività come firmwarista (cavoli, sto invecchiando...) non ho mai preso la decisione di scrivere uno scheduler per le attività che il microcontrollore doveva gestire, ed ho demandato il tutto ad un insieme di funzioni e strutture non propriamente organizzate. Per aiutarmi in questo compito, qualche anno fa ho scritto una libreria (il termine è veramente eccessivo) per astrarre il timer fisico del microcontrollore, in particolare il PIT dei Kinetis della NXP, la quale chiamava una callback allo scadere di un determinato timer logico. Come potete immaginare, alla lunga questa struttura ha iniziato ad essermi stretta, soprattutto al crescere della complessità delle mie applicazioni!

Con questa esigenza è nata WETS, l'acronimo di Warcomeb Easy Task Scheduler. WETS è una libreria che crea una scheduler event-driven, cioè basato esclusivamente sulla gestione ed esecuzione di eventi. Nonostante nel nome sia presente la parola task, nella libreria non si tiene conto di questo concetto, relativamente più alto rispetto al suo obiettivo. L'obiettivo della libreria è riuscire a gestire tre tipi di eventi:

  • asincroni, sono eventi che vengono creati in maniera asincrona in base al ciclo ed allo stato dell'applicazione e che vengono gestiti appena possibile dallo scheduler, ovviamente rispettandone la priorità,
  • ritardati, sono eventi creati in maniera asincrona come i precedenti, ma che vengono processati dopo uno specifico timeout definito in fase di creazione,
  • ciclici, sono invece eventi che una volta creati vengono processati ciclicamente allo scadere di uno specifico timeout.
Per gestire questi tipi di eventi, i prototipi delle funzioni principali sono riportati di seguito:

// Async Events

WETS_Error_t WETS_addEvent (pEventCallback cb, 
                            uint8_t priority, 
                            uint32_t event);

WETS_Error_t WETS_removeEvent (uint8_t priority, 
                               uint32_t event);

bool WETS_isEvent (uint8_t priority, 
                   uint32_t event);

// Delayed Events

WETS_Error_t WETS_addDelayEvent (pEventCallback cb,
                                 uint8_t priority,
                                 uint32_t event,
                                 uint32_t timeout);

WETS_Error_t WETS_removeDelayEvent (uint8_t priority,
                                    uint32_t event);

//  Cyclic Events

WETS_Error_t WETS_addCyclicEvent (pEventCallback cb,
                                  uint8_t priority,
                                  uint32_t event,
                                  uint32_t cycle);

WETS_Error_t WETS_removeCyclicEvent (uint8_t priority,
                                     uint32_t event);
                            
Dai prototipi delle funzioni è possibile notare alcune peculiarità della libreria:
  1. Gli eventi sono suddivisi in gruppi di priorità. Questo significa che lo scheduler si occuperà prima degli eventi attivi presenti nel gruppo con priorità zero, per poi salire a quelli dei gruppi superiori. Di default sono presenti quattro gruppi (priorità che va da zero a tre), ma, in base alle caratteristiche del microcontrollore e della sua memoria, la macro che contiene il valore massimo può essere sovrascritta con un numero più grande.
  2. Gli eventi per ogni gruppo possono essere al massimo 32, infatti questi devono essere espressi utilizzando un singolo bit dell'uint32_t messo a disposizione. Il bit MSB (Most Significant Bit) rappresenta l'evento a priorità più alta.
  3. I tempi per gli eventi ritardati o ciclici sono espressi in millisecondi

La libreria è attualmente in fase di scrittura e test, e conto di rilasciare la prima versione entro la fine di agosto. A corredo ci sarà un nuovo articolo con esempi applicativi e documentazione generata con Doxygen... nel frattempo seguite il repository su GitHub e se avete dubbi o richieste o consigli non esitate ad aprire una nuova issue!

Stay scheduled! :)