Introduzione a FreeRTOS (lezione 1)
System on Chip (SoC) è una tecnologia che permette di integrare tutti i componenti di un sistema elettronico su un singolo PCB (Printed Circuit Board).
Questo ha portato all’utilizzo diffuso di sistemi a microcontrollori, ovvero sistemi “general purpose” anche in ambiente maker.
I microcontrollori sono molto utilizzati grazie alle dimensioni ridotte, dal basso costo , dal continuo incremento delle prestazioni e delle periferiche integrate.
Nel 2005, il progetto Arduino ha reso i microcontrollori più accessibili agli studenti, semplificando notevolmente la loro programmazione.
Da allora, hobbisti e professionisti hanno utilizzato e sfruttato le enormi potenzialità del sistema Arduino.
FreeRTOS è un sistema operativo (Real-Time Operating System, RTOS) che è stato recentemente introdotto nel framework software Arduino.
L’uso di un sistema operativo come FreeRTOS ha il grosso vantaggio di poter gestire più attività in parallelo e di rispettare tempi stringenti di esecuzione dei processi, pertanto è usato anche per sistemi che richiedono elevata affidabilità.
Tuttavia, non tutte le piattaforme hardware Arduino supportano FreeRTOS, poiché si richiedono risorse aggiuntive come SRAM (Static Random Access Memory) e potenzialità maggiori di calcolo.
Per i microcontrollori con prestazioni e dimensioni di memoria sufficienti per la gestione del sistema operativo, FreeRTOS mette a disposizione delle API (Application Programming Interface) per rendere la scrittura di applicazioni molto più semplici.
L’approccio usato sui microcontrollori, che non usano un sistema operativo come FreeRTOS, è quello di eseguire in polling gli eventi d’ingresso.
Facciamo un esempio molto semplice, supponiamo che dobbiamo gestire un ingresso collegato ad un pulsante, dei dati seriali in ingresso, leggere la temperatura rilevata da un sensore, e in funzione dello stato degli ingressi bisogna produrre una determinata uscita come accendere un diodo LED, chiudere un relè e stampare sul terminale dei dati.
L’approccio di leggere i dati in polling, può funzionare per piccoli progetti, ma se abbiamo un numero considerevole di periferiche, soprattutto per sistemi in cui si richiede un tempo di risposta rapido, ci potrebbero essere dei problemi di gestione.
Se noi strutturiamo il programma in sottoprogrammi eseguibili in modo indipendente, il problema diventa molto più semplice da gestire, nell’ambiente FreeRTOS, quest’ultimi sono definiti “task”.
Per esempio il task che rileva la pressione e gestisce il rimbalzo di un pulsante sull’ingresso GPIO, diventa una semplice funzione indipendente.
E con questa logica si può dividere un progetto molto complesso in tanti sottoprogrammi.
Nei primi anni dell’informatica, i mainframe potevano eseguire solo un programma alla volta, i tempi di elaborazione erano relativamente lenti e poco efficienti.
Con la nascita dei sistemi operativi come Time Sharing Option (TSO), è stato possibile condividere la risorsa di un computer con più utenti, dando l’illusione di eseguire più programmi contemporaneamente attraverso l’esecuzione concorrente, ovvero il salvataggio e il ripristino dei registri di programmi diversi in rapida successione.
Oggi, questo approccio , è usato anche sui microcontrollori, grazie all’aumento della potenza di calcolo, della memoria disponibile e l’ottimizzazione dei sistemi operativi RTOS (Sistema Operativo in Tempo Reale).
La pianificazione preventiva, in cui le attività vengono sospese e riprese in base a un timer hardware, permette di eseguire attività in multitask, consentendo ai progettisti di suddividere le applicazioni complesse senza dover pianificare la schedulazione manualmente.
Tuttavia, l’esecuzione simultanea di attività porta con sé nuovi problemi, come la comunicazione sicura tra i diversi task e la loro sincronizzazione, questi aspetti sono gestiti dal S.O. come FreeRTOS.
FreeRTOS è progettato per gestire progetti complessi, ad esempio, le code dei task sono state progettate affinché si tenga conto delle priorità di ogni task.
Un’attività, definita in fase progettuale con alta priorità, può richiedere immediatamente l’utilizzo del microcontrollore ad un’attività con priorità inferiore.
FreeRTOS libera il progettista software da tutte le operazione di schedulazione delle attività, quest’ultimo può concentrare tutta la sua attenzione sullo sviluppo dell’applicazione.
Le funzioni
Gli identificativi delle funzioni sono preceduti da due componenti:
• Il tipo di dati del valore restituito
• Il file in cui la funzione è definita
Ecco alcuni esempi:
• vTaskPrioritySet() restituisce un void e viene definito all’interno del file di FreeRTOS task.c.
• xQueueReceive() restituisce una variabile di tipo BaseType_t e viene definita all’interno del file di FreeRTOS queue.c.
• vSemaphoreCreateBinary() restituisce un void e viene definito all’interno del file di FreeRTOS semphr.h.
In questo contesto, il prefisso “v” significa che la funzione non restituisce alcun valore, mentre il prefisso “x” significa BaseType_t: per la piattaforma Espressif, definito come una variabile senza segno 32 bit intero (uint32_t).
File Header
Quando si utilizza FreeRTOS sono richiesti gli statement #include.
All’interno dell’ambiente di programmazione Arduino per ESP32, questi sono già forniti internamente.
Tuttavia, quando si utilizza ESP-IDF o una piattaforma diversa, sarà necessario conoscere i file header.