FreeRTOS per x86

Sul blog di Elettronica Open Source puoi leggere non solo tutti gli articoli Premium riservati agli abbonati Platinum 2.0 e inseriti nella rivista Firmware 2.0 (insieme ad articoli tecnici, progetti, approfondimenti sulle tecnologie emergenti, news, tutorial a puntate, e molto altro) ma anche gli articoli della Rubrica Firmware Reload. In questa Rubrica del blog abbiamo raccolto gli articoli tecnici della vecchia rivista cartacea Firmware, che contengono argomenti e temi evergreen per Professionisti, Makers, Hobbisti e Appassionati di elettronica. FreeRTOS è un kernel open source, portabile, real-time ed estremamente ridotto che può essere utilizzato in applicazioni di tipo commerciale o anche su piattaforme x86, se non abbiamo particolari esigenze.

FreeRTOS è uno dei maggiori kernel disponibili per qualsiasi tipo di applicazioni commerciale e non, insieme al prodotto di punto di casa Micrium che copre una fetta molto importante del mercato. Diversi costruttori di microcontrollori offrono particolari porting di FreeRTOS, come la Fujitsu Microelectronics Europe che ha da diverso tempo proposto il porting di FreeRTOS sui propri microcontroller appartenenti alle serie 16FX e FR MB91460. Infatti, FreeRTOS è un mini-kernel real-time open source portabile e completamente gratuito, che può offrire una risposta conveniente per i diversi segmenti di mercato tra commerciali e più spiccatamente industriali. Accanto alla versione free del prodotto esiste anche la disponibilità di una linea più rispondente alle esigenze real-time per le piattaforme industriali sponsorizzata da Wittenstein high integrity systems con una licenza commerciale appositamente predisposta per queste particolari esigenze. In effetti, per le applicazioni safety-critical è disponibile Wittenstein SafeRTOS, una soluzione conforme allo standard IEC 61508 Safety Integrity Level (SIL) 3 sempre basata sulla versione aperta di FreeRTOS.

Questa variante è stata specificatamente realizzata per il mondo dei microcontrollori a 32 bit con un disegno che ha potenziato l’ottimizzazione e la sua scalabilità, il footprint di SafeRTOS rientra, tipicamente, nell’intervallo dai 7 a 14 Kb. Ricordo che i microcontrollori Fujitsu delle serie 16FX e FR MB91460 con porting FreeRTOS sono già oggi disponibili. In realtà il panorama industriale italiano e non, offre una vasta gamma di scelta di questo tipo. Per essere più precisi possiamo, ad esempio, riferirci al Bora con processore Xilinx Dual ARM Cortex-A9 ZYNQ XC7Z010/ZC7Z020 con una frequenza di lavoro di 800MHz e disponibile con Linux e FreeRTOS o Touch32. Quest’ultima è basata su un’interfaccia touch screen a microprocessore che abbina le caratteristiche di compattezza e flessibilità con l’apertura verso il mondo della comunicazione grazie alla disponibilità di una gamma di moduli di I/O via CAN, seriale RS485 e USB. Touch32 è basato su ARM Cortex M3 riuscendo ad abbinare la potenza di un multitasking, di un filesystem FAT utilizzando un kernel minimale basato su FreeRTOS. Il codice sorgente di FreeRTOS è liberamente disponibile, un aspetto da non sottovalutare. Infatti, grazie a questa particolarità, può essere utilizzato in sessioni di studio o approfittarne per comprenderne il suo funzionamento nei minimi dettagli e di fare, senza particolari problemi, il porting verso soluzioni più disparate. In effetti, oltre a essere utilizzato in soluzioni tipicamente embedded, può anche essere inserito in sistemi già collaudati, quali piattaforme Windows. In questo caso, però, è opportuno fare una necessaria precisazione. Se pensassimo di utilizzare FreeRTOS in sistemi Windows, o Dos magari con FreeDOS, dovremmo rinunciare alle sue prerogative di real-time: questa esigenza può essere fortemente sentita per quelle applicazioni dove è necessario far convivere differenti architetture software. La baseline disponibile di FreeRTOS dispone già al suo interno di applicazioni per differenti architetture hardware. Per la variante x86 Windows sono presenti due applicazioni demo: la prima utilizza l'edition Express di Visual Studio, mentre la seconda utilizza gli strumenti gratuiti GCC/Min-GW ed Eclipse. In questo caso, la parte x86 è eseguita in emulazione DOS, mentre la sezione ARM, ad esempio, è simulata sotto un’altra finestra resa disponibile.

FreeRTOS offre diverse particolarità che possono essere molto utili a qualsiasi progettista software. Infatti, accanto alla scelta tra due diverse politiche di schedulazione, preemptive e cooperative, è possibile anche inserire, attraverso degli opportuni hook, delle funzioni richiamabili nel processo di schedulazione. La schedulazione, poi, in FreeRTOS può essere configurata prevedendo, per l’appunto, la possibilità di scegliere tra preemptive e cooperative. Grazie a questa flessibilità è possibile sfruttare le coroutine, task a peso leggero che utilizzano poca memoria. È bene precisare che tutte le misure temporali necessarie al kernel si basano su un tempo misurato nella schedulazione: una variabile preposta allo scopo è incrementata a ogni tick di sistema al fine di garantire risoluzioni apprezzabili e significative. Questo conteggio è utilizzato dallo schedulatore, ogni volta che il contatore di tick è incrementato, il kernel si preoccupa di controllare, in base al valore assunto dal contatore stesso, se ci sono task fermi a una particolare condizione per riattivarli o, al contrario, sospenderli. Esiste una funzione di sistema che può essere utile per leggere il conteggio dei tick, ovvero la xTaskGetTickCount(). Non solo, attraverso gli hook presenti nel sistema possiamo agganciare nostre funzioni al tick di sistema: questo ci consente, ad esempio, di eseguire un task a una particolare frequenza legata al tick di sistema. Come ogni altro sistema operativo, anche in FreeRTOS è possibile sfruttare un algoritmo di scheduling basato su priorità sulla base delle priorità dei task: il task con la più alta priorità ha diritto all’uso esclusivo della CPU. Per rilasciare l’uso della CPU, un programma in FreeRTOS può sfruttare la task delay nelle due forme: vTaskDelay() e vTaskDelayUntil(). Queste funzioni, sempre di sistema, sono utilizzate quando vi è la necessità di bloccare un task per un dato numero di tick o di riattivare l’esecuzione di un particolare task.

Figura 1: Prompt di debug per FreeRTOS

IL BSP DI FREERTOS

La pagina ufficiale di FreeRTOS fornisce una spiegazione dettagliata delle differenze tra le diverse soluzioni di FreeRTOS ufficialmente supportate. FreeRTOS garantisce il pieno supporto per Altera, Tamil, Cadence, Cortus, Cypress, Energy Micro, Freescale, Infineon, Luminari Micro, Microchip, NEC, Microsemi, NXP, Renesas, Silicon Labs, Espansioni (ex Fujitsu), ST Microelettronica, Sinopsi ARC, Texas Instruments, Xilinx, x86 (real mode), x86/Windows Simulator. In particolare, per la linea x86 real mode, FreeRTOS può essere utilizzato in una grande varietà di soluzioni PC/AT o single board computer inclusi i sistemi PC/104. In questo caso, come ambiente di sviluppo al solito si utilizza OpenWatcom o Borland: FreeRTOS offre un’ampia scelta di BSP o applicazioni Demo. Non solo, l’opzione single board computer, sempre nella famiglia x86, vale per le linee RDC8822 e RDCR1120. Per apprezzare FreeRTOS è prevista anche la possibilità di utilizzare il kernel in modalità simulata con Visual Studio Express Edition o MingW con Eclipse. Questa può essere un’occasione per vedere FreeRTOS all’opera, in assenza di un target reale, in un ambiente Windows senza, però, le prerogative di real-time. Nella distribuzione FreeRTOS scaricabile dal sito di riferimento sono disponibili diversi progetti demo, uno per piattaforma o famiglia, comprensivi di codice sorgente e ampie spiegazioni dettagliate sul loro funzionamento. In particolare, per l’ambiente simulato Windows, è possibile, attraverso delle flag selezionabili in fase di compilazione, decidere quale particolare applicazione utilizzare. Non solo, per ogni demo, o applicazione per ogni singolo processore o architettura, è disponibile il file di configurazione FreeRTOSConfig.h.

Questo file, in base alle opzioni selezionate al suo interno, ci permette di ricavare una particolare applicazione ritagliata per una specifica CPU o ambiente demo. A questo scopo, in Riquadro 1, possiamo vedere la configurazione per una demo ritagliata per una applicazione residente su PC, mentre nel Riquadro 2 si pone in evidenza una specifica configurazione utilizzando il file di lavoro “FRConfig.h”. La flessibilità presente in FreeRTOS è veramente interessante tanto da prevedere, oltre a diverse configurazioni possibili, differenti piattaforme simulate non basate su sistemi virtuali quali Qemu, ma vere soluzioni hardware con funzionalità ridotte: infatti, è possibile sfruttare il PC con Windows con gli eventi asincroni simulati. In particolare, attraverso la costante main- CREATE_SIMPLE_BLINKY_DEMO_ONLY, definita nel file main.c, è possibile selezionare una delle due applicazioni presenti. Con mainCREATE_SIMPLE_BLINKY_ DEMO_ONLY a 1 la funzione main chiamerà la funzione main_blinky() implementata in main_blinky.c: questa funzione si basa su di un applicativo con due task e una coda. Un task spedisce continuamente un valore all’altro task attraverso una coda, il task ricevente stampa un messaggio ogni volta che riceve il valore dalla coda. Al contrario, con mainCREATE_SIMPLE_ BLINKY_DEMO_ONLY posta a 0, il main chiama la funzione main_full().

Riquadro 1: File di configurazione per PC

 

Riquadro 2: FRConfig.h (specifica configurazione per PC)

SIMULARE UN INTERRUPT

Una delle cose più interessanti di questa piattaforma è la possibilità di utilizzare degli eventi asincroni simulati attraverso il ricorso alle funzioni ISR. Queste funzioni si basano sul prototipo:

unsigned long ulInterruptName( void );

Dove con "ulInterruptName" si identifica il nome della funzione stessa: ricordiamo che la funzione deve essere eseguita all’interno di un context switch. Se volessimo installare un handler per uno specifico interrupt simulato allora dovremmo fare ricorso alla funzione definita nella sezione del porting di Win32 di FreeRTOS, ovvero utilizzare la vPortSetInterruptHandler(). Il prototipo della funzione è:

void vPortSetInterruptHandler( unsigned long ulInterruptNumber, unsigned long (*pvHandler)( void ) );

pvHandler è il puntatore alla funzione, mentre ulInterruptNumber deve assumere un valore univoco tra 3 e 31: questo vuol dire che possono essere gestiti fino a 29 interrupt simulati. Quando un task di FreeRTOS è eliminato dal sistema, nell’ambiente Windows simulato sarà terminato il thread responsabile della sua esecuzione: questo dimostra che, nella versione simulata di FreeRTOS per Win32, esiste una netta corrispondenza tra thread di Windows e task di FreeRTOS. Pare opportuno anche ricordare che, in questa particolare configurazione, esiste un limite propriamente fisico, in altre parole le risorse associate al thread non sono recuperate ma rimangono sempre assegnate: questo comporta un serio problema, esiste un limite al numero di volte che la funzione API FreeRTOS vTaskDelete() può essere chiamata. È bene anche precisare che, anche se il limite è molto elevato, è doveroso tenerne conto. Per simulare un interrupt asincrono periodico è necessario tenere conto di alcuni accorgimenti. Il tick del sistema è simulato da un thread di Windows a più alta priorità che dovrà periodicamente fare la preemption dei thread a più bassa priorità che sono in esecuzione in quel momento. Per questa ragione il periodo del tick di sistema è legato al limite del rate del timer di Windows: ecco perché FreeRTOS, in Win32, appare lento e poco preciso. Al contrario, per simulare il gestore di un interrupt si deve ragionare diversamente. Il gestore di un interrupt in FreeRTOS è posto in esecuzione da un secondo thread a più alta priorità perché, vista la sua priorità, può fare la preemtpion sui thread a più bassa priorità che eseguono task all’interno del sistema. La gestione è concordata tra l’interrupt di sistema simulato e i thread di Windows.

Articolo della rivista cartacea Firmware Anno 2015 - Numero 114-115

Scarica subito una copia gratis

Scrivi un commento

Send this to a friend