È veramente indispensabile utilizzare un sistema operativo real-time? Quali sono le ragioni per utilizzare un RTOS in un sistema dedicato? Vediamo quali sono gli aspetti da tenere presenti per decidere l’acquisto di un sistema operativo per sistemi embedded.
Non è detto che un sistema dedicato deve disporre di un RTOS real-time. Infatti una grossa fetta delle applicazioni commerciali non utilizzano un sistema operativo, ma si basano su un modello ciclico basato anche su evento. In questo articolo si vogliono dare indicazioni di massima sulle ragioni che possono decidere l’acquisto di un kernel real-time.
LE RAGIONI
Il firmware potrebbe essere semplicemente un ciclo software principale dove all’interno trovano posto diverse funzioni: il tempo di CPU viene così diviso in maniera paritaria, infatti non ci sono funzioni più prioritarie a meno di un evento asincrono. Un approccio di questo tipo può rappresentare la scelta ideale per diverse applicazioni, una decisione suggerita anche da ragioni economiche. Quali sono i motivi che possono dare un contributo decisivo per l’acquisito di un kernel real-time? Vediamo le possibili ragioni economiche e tecniche:
Economiche
- Il costo, tra royalty e licenze, di un sistema operativo è abbastanza alto. Se, poi, per ragioni di progetto non possiamo utilizzare un sistema leggero, il costo può diventare insostenibile perché possono essere introdotti, in ogni caso, dei costi fissi.
- Utilizzare un sistema operativo vuol dire che occorre dotarsi di sistemi di test mirati e spesso anche costosi.
- Se il sistema operativo viene modificato, anche in parte, chi risponde della bontà delle modifiche stesse? È necessario coinvolgere gruppi terzi per verificare le modifiche? E se il sistema operativo aderisce a uno standard, chi certifica che la modifica non pregiudica l’aderenza alle normative in uso? A questo punto si possono innescare processi di verifica a volte anche costosi.
Tecniche
- Test. L’uso di un sistema operativo introduce, da un punto di vista tecnico, nuove problematiche: chi garantisce che il sistema operativo sopperisce alle sue funzionalità? In questo caso occorre studiare e mettere a punto dei test mirati.
- Codice ombra. L’uso di primitive del sistema operativo introduce potenzialmente un altro problema: se c’è un malfunzionamento e questa coinvolge anche funzioni di libreria le eventuali indagini risultano abbastanza difficili perché è necessario considerare queste funzioni chiamate ombra.
- Supporto. Il costruttore di un sistema embedded una volta terminato il suo ciclo di sviluppo deve approntare politiche di marketing per vendere il frutto del suo lavoro, ma deve anche garantire il supporto tecnico agli eventuali compratori e quindi anche, indirettamente, sul sistema operativo che è parte della sua applicazione.
Accanto a queste considerazioni che sembrano sconsigliare l’uso di un sistema operativo, ne esistono altre che ne sollecitano il loro utilizzo. Le ragioni che sostengono l’uso di un sistema di questo tipo possono riguardare i seguenti argomenti:
Uso di librerie
L’uso di un sistema operativo permette di utilizzare una serie di librerie sufficientemente standardizzate e testate, questo permette la portabilità delle nostre applicazioni.
Safety del codice
Un sistema operativo mette a disposizione il concetto di stratificazione delle chiamate: il software applicativo può interagire con i dispositivi fisici non più direttamente ma in maniera mediata secondo un meccanismo già consolidato e testato. Il sistema operativo può mediare attraverso l’uso di metodi tra i diversi strati, per esempio per mezzo di primitive di sincronizzazione per l’accesso alle risorse condivise e attraverso la notifica degli eventi sincroni o asincroni.
Documentazione
Acquistare un sistema operativo vuol dire ottenere un prodotto sufficientemente testato e documentato. Un insieme di librerie con descrizioni tecniche corredato da esempi d’uso.
Manutenzione/sviluppo
Utilizzare un sistema operativo permette di adoperare concetti quali la modularità. In questo caso diventa più facile pianificare attività suddivise in macrofunzioni adoperando le primitive messe a disposizione del sistema.
La scelta di un sistema operativo: aspetti tecnici
Per fare una scelta obiettiva sulle diverse proposte tecniche, l’utilizzatore diretto del sistema non dirige la sua scelta sulla base delle argomentazioni commerciali, ma si dedica all’esame degli aspetti più spiccatamente tecnici. La domanda che deve porsi è quali sono le prerogative di questo sistema operativo? Qual è la sua occupazione di memoria? Il supporto tecnico è efficiente? Quale algoritmo di schedulazione implementa? In seguito si è fatto un piccolo riassunto delle caratteristiche che deve avere un sistema di questo tipo. Il footprint, termine che vuole indicare l’occupazione di risorse richieste, è un aspetto non secondario da tenere presente nella scelta di un sistema operativo embedded. Il footprint che il tecnico utilizza dipende, in maniera diretta, sulla quantità di memoria disponibile. La quantità di memoria incide direttamente sul numero dei processi consentiti, infatti, se utilizziamo LynxOS un processo occupa 1073 bytes, mentre con ThreadX circa 200 bytes. In figura 1 il footprint di alcuni sistemi operativi. In ogni caso le prerogative che deve avere un generico sistema operativo sono riassunte in questo modo: Schedulatore, Politiche di gestione delle risorse condivise, Meccanismi di sincronizzazione, Board Support Package (BSP), Timers, Standard, Meccanismi di comunicazione, Gestione della memoria, Memory Protection, Moduli aggiuntivi (stack di protocollo e interfacce grafiche), Moduli aggiuntivi: strategie di debug. Eccoli in dettaglio (figura 1).
Schedulatore
Nella maggior parte dei sistemi operativi commerciali o anche open, l’algoritmo di schedulazione è di tipo a priorità. È un algoritmo abbastanza semplice perché ogni task deve avere una priorità diversa. Altri sistemi operativi permettono di condividere la stessa priorità, suddividendo equamente il tempo di CPU tra i task ad uguale priorità mediante un meccanismo chiamato scheduling round robin cooperativo, in questo modo è il processo stesso che deve rilasciare la CPU, o attraverso il meccanismo round robin con prelazione, in questo caso il processo viene forzato a rilasciare la CPU a seguito di un evento asincrono o per il raggiungimento di un numero prestabilito di time slices, o ancora per l’esaurimento del tempo allocato al task per la sua esecuzione (time budget). Esistono poi altre considerazioni da tenere presenti
- Politiche in tempo e spazio, in questo caso è applicabile lo standard di riferimento ARINC-653 dove si prevede uno schedulatore che gestisce le partizioni in tempo e spazio, le partizioni in spazio utilizzano le prerogative di un MMU.
- Altri prevedono delle code di priorità di tipo FIFO e Round-Robin.
- Esistono poi meccanismi per risolvere il problema dell’inversione di priorità, questi si basano su priority inheritance e priority ceiling.
Politiche di gestione delle risorse condivise
Un sistema operativo che si rispetti deve prevedere algoritmi e servizi che permettono di garantire l’accesso esclusivo alle risorse del sistema.
Meccanismi di sincronizzazione
Un sistema operativo deve prevedere, per esempio, interfacce software per sincronizzare i processi sulla base di determinati eventi in maniera sincrona o asincrona.
Board Support Package (BSP)
Sono moduli software che permettono di portare il sistema operativo su differenti architetture. Di solito insieme al BSP è fornito anche un bootloader che ha lo scopo di predisporre una scheda per caricare il sistema operativo, il bootloader è costruito su schede standard e in ogni caso è necessario fare un opportuno lavoro di adattamento per schede specifiche.
Timers
Servizi che permettono al programmatore di sospendere un task per un determinato quanto di tempo, allo scadere di questo slot temporale il sistema operativo deve rimettere in esecuzione il processo, sempre secondo le politiche di schedulazione in uso.
Standard
Esistono diversi standard che un produttore deve seguire per rispondere a determinati requisiti di certificabilità. Esistono per esempio standard quali ARINC-653, DO-178B, ED-12B, DO-254, ED-80, DO-278.
Valid-653™ è una implementazione dello standard ARIC-653 con l’interfaccia APEX (Application/EXecutive) per Integrated Modular Avionics (IMA) systems ed altre applicazioni che vengono definite safety-critical environments. Il sistema Valid-653™ è anche una implementazione nativa dell’ARINC-653 e non richiede nessun’altro sistema operativo. Utilizzando la semantica dello standard ARINC-653, questo sistema operativo implementa il concetto di partizioni sia in tempo che in spazio. La divisioni della partizioni in spazio sono garantite mediane l’uso del MMU, ad ogni partizione è garantita uno slot di esecuzione definita dal sistema. I threads di ciascuna partizione sono schedulati sulla base della politica prioritàpreemptive.
Meccanismi di comunicazione
Ogni sistema operativo fornisce delle primitive per permettere la comunicazione tra processi, parliamo di IPC, mailbox, queue e pipe. Le interfacce di questi meccanismi o sono proprietarie o aderiscono a uno standard, di solito per queste si tenta di seguire lo standard Posix. L’adesione ad uno standard implica anche definire interfacce particolari, per esempio se si aderisce allo standard DO-178B, magari level B, vuol dire che il programmatore non potrà utilizzare strutture dinamiche ma solo statiche. Particolare attenzione va data nella definizione delle strutture, per esempio le interfacce possono anche essere utilizzate sotto interrupt? Se la risposta fosse positiva, allora sarà necessario pensare a politiche di protezione dei dati.
Gestione della memoria
A seconda del sistema operativo, possono esserci soluzioni basate sull’allocazione dinamica o statica della memoria. Un sistema dedicato ha, per definizione, poca memoria.
Nei sistemi dedicati e, per maggior ragione, in relazione agli standard Do-178B la primitiva malloc non viene utilizzata perché si preferisce utilizzare delle politiche di allocazione statica della memoria. Diversi sistemi operativi, tra cui TNKernel, utilizzano un altro meccanismo, chiamato fixed-sized memory pool. Questa è un particolare gestione che consente l’uso di partizioni fisse di memoria utilizzate in maniera dinamica. In un sistema di questo tipo si dispone di un’area di memoria dove i blocchi, di dimensioni fisse, sono disponibili per essere allocati. Se un processo non ottiene un blocco di memoria allora questo è posto in una coda in attesa del blocco richiesto. Ogni sistema che implementa una politica di questo tipo mette a disposizione un insieme di primitive, a titolo d’esempio la tabella 1 mostra quali interfacce rende disponibile TNKernel.
Memory Protection
Un sistema operativo Real-time di solito fornisce una completa protezione di memoria per i task utente, sfruttando i meccanismi hardware di memory protection, mediante l’utilizzo di una MMU per esempio. Per questo, un sistema operativo può garantire il Secure memory protected operation, Secure tasks, Secure interprocess communication e il Secure device drivers.
In definitiva può fornire un sistema di protezione per l’accesso a moduli specifici senza che un errore possa pregiudicare l’esecuzione dell’intero sistema.
Moduli aggiuntivi: stack di protocollo e interfacce grafiche
Un produttore di un sistema operativo è in grado di offrire una serie di moduli opzionali e aggiuntivi che consentono di gestire in maniera integrata, per esempio, le seguenti funzioni:
- Stack di protocollo TCP/IP, comprensivo di Web Server e Web Browser;
- Protocolli ATM, SS7, ISDN, X.25, V5, Frame
Relay;
- Interfaccia grafica PEG con driver per svariati LCD e Video controller;
- File System;
- Moduli per la gestione degli errori e strategie di recovery;
- Shell di comando, come VxWorks.
Moduli aggiuntivi: strategie di debug
Da diversi anni i produttori di sistemi operativi non si limitano più a fornire lo strato del kernel, ma offrono anche soluzioni integrate di debug e di compilazione, come l’IDE AdaMulti della Green Hills. Queste offerte includono:
- Possibilità di debuggare più tasks attraverso diversi AddressSpaces, in un sistema multiprocessore (ogni task nella propria finestra di debug).
- Possibilità di creare ed aprire una nuova finestra di debug, contestualmente alla creazione di un nuovo task.
- Possibilità di debug multi-task sia tramite ethernet che seriale per la maggior parte delle schede esistenti.
- Possibilità di visualizzare il tempo di esecuzione relativo di tutti i task (incluso il task “idle”).
- Possibilità di monitorare lo stato delle variabili in real-time con la possibilità di mettere di associare delle azioni ad una certa occorrenza.
È chiaro che soluzioni di questo tipo sono certamente utili, ma fanno comunque lievitare il prezzo del prodotto: sono da valutare attentamente.
La scelta di un sistema operativo: aspetti commerciali
Quando si valuta l’uso di un sistema operativo per una applicazione dedicata occorrono tenere presenti diversi aspetti, da considerazioni commerciali a quelli tecnici. Le scelte disponibili possono anche non essere mutuamente esclusivi, nel senso che i produttori possono prevedere formule commerciali che prevedono royalty e anche licenze particolari. In questo caso, di solito, si formula un accordo di massima ( a volte è chiamato accordo quadro) tra l’utilizzatore e il produttore del sistema operativo.
- royalties, per ogni singolo oggetto venduto contenente il binario del sistema operativo, di solito il produttore richiede una somma di denaro da corrispondere per l’uso del sistema stesso: il produttore detiene i diritti sul sistema operativo e questo viene di solito indicato con il termine di royalty.
- costi per le licenze per prodotto o linea di prodotti. Oggi quasi tutti i costruttori di sistemi operativi hanno abbandonato l’uso delle royalty, queste sono state sostituite dalle licenze. La licenza è, banalizzando, il riconoscimento del produttore per l’uso del binario del sistema operativo in un numero imprecisato di oggetti dello stesso tipo, prodotto, o di tipo leggermente diverso, linea di prodotti. Chiaramente la licenza è molto elevata se gli oggetti sono pochi e, al contrario, è bassa su grossi quantitativi.
- costi per le licenze per postazioni di lavoro aggiuntive. Sotto questa denominazione si identifica un altro accordo commerciale. Può capitare che il produttore richieda una licenza per ogni programmatore, o gruppi di programmatori, per utilizza il prodotto per lo sviluppo di un progetto. Puà essere applicabile sia il formato binario o anche il codice sorgente: in questo caso il costo aumenta notevolmente.
- costi per le licenze del codice sorgente. Il produttore può, a fronte di un accordo commerciale, fornire il codice sorgente per modifiche anche parziali del sistema dietro particolari requisiti imposti dal progetto. Il costo di una simile licenza è molto alta e non è comparabile con quella binaria, chiaramente una scelta di questo tipo è obbligatoria se esistono particolari requisiti o vincoli di progetto.
- Ogni produttore non si limita a fornire un kernel real-time ma offre soluzioni. Ogni soluzione che propone risponde a una determinata esigenza, così può offrire ambienti integrati di compilazione e debug o anche moduli aggiuntivi quali filesystem: insomma, sono sistemi altamente scalabili. È chiaro che il costo di un ambiente è direttamente alle soluzioni che il cliente richiede.
- Standard. L’aderenza ad uno standard di un sistema operativo fa certamente lievitare il costo. Ma questo tipo di scelta non dipende unicamente dalle singole valutazioni discrezionali, ma occorre anche verificare le reali esigenze del programma.
CARATTERISTICHE DI ALCUNI RTOS
Vediamo le caratteristiche di quattro sistemi operativi che occupano una posizione di mercato non indifferente, sia da un punto di vista commerciale e sia nel mondo open. Questo elenco non vuole assolutamente privilegiare nessuno, se alcune informazioni sono assenti è perché non si sono ottenuti dei riferimenti espliciti dai distributori o dal sito del produttore.
FreeRtos
È un sistema operativo Open source, portabile, il codice sorgente è disponibile liberamente e non ci sono royalty da conferire ed è corredato da un mini real time scheduler. La fascia di mercato è quella dei piccoli microcontrollori. Scritto in C con parti in assembler, il kernel è abbastanza facile da modificare per portarlo su altre architetture poiché dispone di molte informazioni tecniche sul sito di riferimento.
Il suo footprint è abbastanza contenuto ed è rivolto all’essenziale. Ci sono poi diversi BSP disponibili. Il tipo di schedulazione adottata è basata sulla priorità.
VXWorks
VxWorks è parte integrante di Tornado®, un IDE per piattaforme embedded. Questo RTOS è uno degli sistemi operativi più utilizzati nel settore industriale. Tornado® comprende una serie di strumenti di sviluppo, quali compilatori e utilities. VxWorks è poi estremamente flessibile e dispone di più di 1800 interfacce (API) che consentono al programmatore di rapportarsi in maniera efficiente con i moduli hardware e software integrati con Tornado®. È disponibile per una varietà di microprocessori ed è utilizzato anche per applicazioni critiche. Garantisce il supporto verso queste interfacce di rete:
TCP/IP, FTP, SMTP, NFS, PPP, RPC, Telnet, BSD 4.4, TCP/IP networking,IP, IGMP, CIDR, TCP, UDP, ARP, RIP v.1/v.2, Standard Berkeley sockets, zbufs (a.k.a., zero-copy sockets), SLIP, CSLIP, BOOTP, DNS, DHCP, TFTP, NFS, ONC RPC, WindNet SNMP v.1/v.2c with MIB compiler - optional, WindNet OSPF.
Sono disponibili diversi BSP per vari microprocessori e schede commerciali. VxWorks garantisce, attraverso sue varianti, la sua adesione a varie normative di riferimento, quale DO-178B e ARINC-653.
Integrity
Elemento di punta della GHS è stato costruito sul microkernel velOSity. Studiato e realizzato per applicazioni per ricavare la massima reliability del sistema. Integrity è disponibile per le architetture PowerPc e MIPS, utilizza il dispositivo MMU per creare partizioni in spazio e in tempo, fornisce un partition scheduling secondo la specifica ARINC-653. Il sistema operativo fornisce interfacce POSIX e proprietarie per utilizzare i servizi di sistema. È possibile la creazione di task in diversi linguaggi quali C, C++ e Ada. Permette il dynamic download dei task e fornisce un analizzatore degli eventi in tempo r In debug permette di mettere dei breakpoint su un task specifico e garantisce il Run-time error control che consiste in eccezioni applicative in caso di accesso errato alla memoria o al superamento dello stack di task. Lo scheduler supporta livelli di priorità multiple che garantiscono percentuali fissate di tempo di CPU all'interno di ogni livello di priorità. Per applicazioni che non richiedono memoria protetta, e necessitano di un footprint minimo e massima efficienza, Integrity può essere usato in kernel mode. In questo modo, Integrity offre un footprint più piccolo e kernel services più veloci.
LynxOS
LynxOS è un sistema operativo realizzato per il mondo real-time. È conforme a POSIX e UNIX- compatibile. LynxOS è un sistema multiprocesso e multithread progettato per applicazioni complesse per il mondo real-time in grado di rispondere a agli stimoli in maniera rapida e deterministica. LynxOS aderisce a diversi standard: è conforme a POSIX 1003.1 e, per la parte real-time, alla normativa 1003.1b e 1003.1c per le estensioni thread. LynxOS è il risultato di un design modulare, questo rende il sistema scalabile e configurabile. Il sistema operativo include le interfacce di sistema di 4.4 BSD e le librerie. Le caratteristice di LynxOS sono riassunte in tabella 2.
ThreadX
È un sistema operativo studiato e realizzato per applicazioni di diverse dimensioni, è real-time ed è esente da royalty. Le sue caratteristiche sono così riassunte:
- Architettura micro-kernel scalare, da 10-15 Kb;
- Context switch ridotto;
- Il codice sorgente viene fornito;
- È integrato con un sistema di sviluppo;
- Le interfacce non sono legate al particolare target in uso e questo permette di portare le applicazioni su differenti soluzioni;
- Esiste la possibilità, secondo ciascuna esigenza, di utilizzare moduli aggiuntivi, quali: stack di protocollo, File System, interfaccia grafica PEG con driver per svariati LCD e Video controller.
Le caratteristiche sono riassunte in tabella 3.
CONCLUSIONE
Da quanto esposto è possibile rendersi conto dell’enorme varietà delle opzioni disponibili. Decidere di acquistare un sistema operativo non è una scelta semplice, ma occorre vagliare ogni aspetto per decidere non in base alle sole considerazioni economiche, ma anche alle reali esigenze del programma.
Articolo davvero molto interessante e ricco di dettagli tecnici difficili da trovare cosi’ ben riassunti un unico posto. Sicuramente uno dei piu’ diffusi, anche per gli “hobbisti avanzati”, e’ il FreeRTOS, portato ormai su diverse piattaforme (PIC32 e altre).
Uno dei porting piu’ interessanti e’ sicuramente quello su piastre XXX-ino, dove FreeRTOS riesce cmq a girare anche su sistemi che non offrono il servizio di MMU (essenziale invece per kernel di tipo Linux).
Sarebbe interessante condividere esperienze su chi abbia gia’ lavorato con FreeRTOS, as it is, oppure avendo tentato dei porting su varie schede.
Io, come ho gia’ accennato, in un altro commento, avevo valutato il porting sulla scheda di sviluppo TRKEA-128, orientata all’automotive. Benche’ ci siano molti porting, il senso generale e di arrivare a implementare una serie di applicazioni di esempio che girino nello stesso modo su tutte le schede portate. L’applicativo tipo “Hello World” su FreeRTOS prevede il solito “Blinky Led”, facendo in modo di poter appunto far blinkare un led da un task generato per quello scopo dal scheduler che FreeRTOS mette a disposizione.
L’intera distro di FreeRTOS, prevede una parte dedicata alla board in esame, che e’ ovviamente custom su quella board e con un dato compilatore (ad esempio, il porting su PIC32 prevede uno o piu’ progetti sviluppati sull’ambiente MPLABX di Microchip). Esiste poi invece una parte che e’ orientata al processore, organizzata in folder, quindi uno o piu’ folder per i PIC, uno o piu’ per i Cortex, etc etc.
Ad esempio, proprio per la TRKEA-128, la parte di processore era gia’ stata portata, poiche’ trattasi di un Arm® Cortex®-M0+ processor. Purtroppo, per i soliti motivi di tempo e di 1000 impegni, non sono riuscito a portare a termine il lavoro, ma sarebbe interessante far parlare 2 task sul CAN, visto che la stessa scheda espone 2 canali di CAN Bus. Pensavo a un BlinkyCAN o simili. Chissà di trovare il tempo e pubblicare qualcosa qui sopra.
Consiglio come lettura anche questo articolo https://it.emcelettronica.com/panoramica-sulle-distribuzioni-linux-embedded-per-architetture-arm
Grazie Maurizio, non so come mi fosse sfuggito 🙂
Interessante anche l’articolo a suo volta suggerito in coda a quello, ovvero lo scheduling sui sistemi real-time.
Complimenti per l’articolo! Personalmente ho lavorato quasi sempre solo con RTOS forniti dai produttori stessi del micro, e ad oggi non riesco a capire quando il mio sistema non ha più bisogno di un sistema operativo. O meglio, capire quando la gestione in task delle operazioni, regolati da uno scheduler, sia effettivamente necessaria rispetto ad un unico ciclo principale dove racchiudo tutto. E capire riuscire a capirlo in fase di pianificazione/progettazione iniziale, senza accorgersi a posteriori di aver sbagliato scelta.
Salve a tutti, sarei interessato ad avere qualche indicazione circa eventuali sistemi operativi real-time utilizzati nel settore automotive ed a loro eventuali “certificazioni” relative a standard di safety. Qualcuno saprebbe gentilmente indicarmi dove posso trovare qualche info? Un grazie anticipato a tutti.