Università Politecnica delle Marche Facoltà di ingegneria Corso di laurea specialistica in Ingegneria Elettronica STUDIO COMPARATO DEI PRINCIPALI SISTEMI OPERATIVI IN TEMPO REALE Tesi di laurea di: Guido Colella Relatore: Chiar.mo Prof. Aldo F. Dragoni Anno accademico 2005 / 2006 ...Dedicato a Dio, alla mia famiglia e ad Alessandra... Indice Indice Capitolo 1 – INTRODUZIONE AI SISTEMI OPERATIVI REAL-TIME 1.1 Introduzione………………………………………………………………………....1 Capitolo 2 – PASSAGGIO DAGLI OS AI SISTEMI OPERATIVI DI NATURA REAL-TIME 2.1 Introduzione………………………………………………………………………....7 2.2 Caratteristiche strutturali di Linux OS……………...………………………….........7 2.3 Predisposizione di Linux ad una politica real-time…...…………………………...11 2.4 Panoramica dei sistemi operativi real-time presenti sul mercato……………….....13 2.4.1 Distribuzioni real-time commerciali……………………………………...14 2.4.2 Distribuzioni real-time open source……………………………….……..15 Capitolo 3 – LE PIU’ DIFFUSE ALTERNATIVE HARD REAL-TIME OGGI SUL MERCATO : RTLINUX ED RTAI 3.1 Introduzione…………………………….………………………………………….16 3.2 RTLinux…………………….……………………………………………………...16 3.2.1 Un’introduzione ad RTLinux…………………………………………....16 3.2.2 Un’aggiunta hard real-time a Linux……………………………………..19 3.3 RTAI……………………………………………………………………………….21 3.3.1 Premessa…………..……………………………………………………..21 3.3.2 Regole per il supporto real-time al kernel di Linux………………… …..22 3.3.3 Un’introduzione ad RTAI………………………………………………..24 3.3.4 L’architettura RTAI………………………..…………………………….25 3.3.5 Real-time application interface…………………………………………..28 3.3.6 Il task real-time…………………………………………………………..29 3.3.7 Il task scheduler……………...…………………………………………..30 I Indice 3.3.8 Scheduling one-shot e periodico………………………………………....30 3.3.9 Operazioni floatig-point……..…………………………………………..32 3.3.10 Interrupt handling…………………..…………………………………..32 3.3.11 Inter-process communication…………………………………………..32 3.3.12 Proc-interface…………………….……………………………………..33 3.3.13 SMP support…………………..………………………………………..34 3.3.14 Linux-RT (LXRT)………….…………………………………………..34 3.3.15 Posix compatibilità API……….………………………………………..35 3.3.16 Performances tipiche……….…………………………………………..36 3.3.17 Sviluppi futuri…………………………………………………………..36 3.4 RTLinux versus RTAI……………...……………………………………………...37 3.4.1 Introduzione……………………………………………………………...37 3.4.2 Licenze e patenti………………………………...……………………….38 3.4.3 La compatibilità con l’API….…………………………………………...40 3.4.4 Architettura e livello di sviluppo……..………………………………….40 3.4.5 Il debug…………………..………………………………………………41 3.4.6 La gestione della memoria……………………………………………….42 3.4.7 La comunicazione tra i processi…………………………………………43 3.4.8 La sincronizzazione……………...………………………………………44 3.4.9 Lo spazio utente real-time……….………………………………………45 3.4.10 Tabella riassuntiva……...………………………………………………48 Capitolo 4 – UN’ESTENSIONE FIRM REAL-TIME DI LINUX : IL KURT 4.1 Premessa……………...……………………………………………………………50 4.2 Un’introduzione al KURT…………………………………………………………50 4.3 Passi salienti dell’RTOS KURT…………………………………………………...51 4.4 La struttura di un “executive process”……………………………………………..54 4.5 La struttura di un processo KURT…………………………………………………54 4.6 Innovazioni dell’RTOS KURT alle system calls………………………………….55 4.6.1 Le system calls nel framework real-time………………………………...55 4.6.2 Le system calls nel modulo di processo…………………………………57 II Indice 4.7 /Proc filesystem……………………………………………………………………60 4.8 Files modificati…………………………………………………………………….60 4.9 Performances dell’RTOS KURT…………………………………………………..61 4.9.1 Il dispatch time dei moduli del kernel e dei processi real-time……….61 4.9.2 KURT versus lo scheduler FIFO soft real-time……………………….63 4.9.3 Distorsioni nello scheduling dovute ai “blocked interrupts”………….72 4.10 Diritti d’autore……………………………………………………………………75 Capitolo 5 – TINYOS E MANTIS : UNO SGUARDO ALL’IMMEDIATO FUTURO DEGLI RTOS 5.1 Introduzione...………..…………………………………………………………….76 5.2 TinyOS...…………………………………………………………………………...77 5.2.1 I componenti…………………………………………………………...78 5.2.2 Split-phase operations………………………………………………….80 5.2.3 Active messages……………………………………………………….81 5.2.4 Miglioramento dello scheduler della versione 1.0 : soluzione all’overload con l’introduzione del concetto di priorità……………………...81 5.3 Mantis OS………………………………………………………………………….83 5.3.1 Kernel e scheduler……………………………………………………..84 5.3.2 Stack protocollare……………………………………………………...84 Capitolo 6 – CONCLUSIONI SULLO STUDIO DEI SISTEMI OPERATIVI REAL-TIME 6.1 Considerazioni finali…….………………………………………………………….86 Bibliografia………………………………………………………………………….....93 III Capitolo 1 Introduzione ai sistemi operativi real-time Capitolo 1 Introduzione ai sistemi operativi real-time 1.1 Introduzione Prima di introdurre i sistemi operativi real-time all’interno della famiglia dei tradizionali sistemi operativi (OS), sarebbe opportuno ricordare per completezza cosa sia e quali compiti svolga un sistema operativo all’interno di un sistema di elaborazione dell’informazione. Un sistema operativo viene definito come il programma “principale” di un calcolatore elettronico (in quanto esso è sempre in esecuzione) che: • Implementa il concetto di macchina virtuale; • Fornisce un’interfaccia verso questa macchina virtuale; • Organizza e gestisce i servizi della macchina virtuale. Il sistema operativo, inoltre, gestisce le entità fisiche del sistema di elaborazione gestendone direttamente l’accesso e organizzandoci sopra delle risorse virtuali senza porsi limiti temporali (perlomeno nella versione General-purpose ). Ogni OS è caratterizzato poi, da un livello di astrazione ben preciso che dipende dal contesto applicativo, cioè essenzialmente dalle applicazioni che quel determinato OS servirà. A tal proposito, gli OS possono essere classificati in base al proprio contesto applicativo in: 1 Capitolo 1 Introduzione ai sistemi operativi real-time • General-purpose; • Servers; • Micro-kernel; • Embedded; • Real-time. All’interno di tale contesto, gli RTOS (acronimo di “real-time operative system”) si collocano come: 1. Sistemi operativi capaci di eseguire tutti i propri “tasks” senza violare specifici vincoli temporali; 2. Il tempo di esecuzione dei tasks può essere calcolato a priori e in modo deterministico sulla base della configurazione sia hardware che software del sistema. Gli RTOS sono contraddistinti dal fatto che, la correttezza della risposta dipende non solo dai valori che assume l’uscita dell’elaboratore ma anche dal tempo in cui questi vengono prodotti. Pertanto, il tempo del sistema deve necessariamente essere sincronizzato con il tempo dell’ambiente circostante (figura 1): 2 Capitolo 1 Introduzione ai sistemi operativi real-time x(t) Ambiente Sistema real-time x(t + D) Fig. 1 – Scenario di un sistema operativo real-time E’ importante sottolineare alcune caratteristiche che contraddistinguono un RTOS che spesso possono dar luogo ad equivoci o ad interpretazioni errate specie per chi si avvicina per la prima volta in tale contesto: • Anzitutto, un sistema in tempo reale non è necessariamente un sistema veloce; ossia “real-time” non è sinonimo di “veloce” ; • Il concetto di velocità è sempre relativo ad uno specifico ambiente; • La velocità deve comunque garantire la correttezza; • L’obiettivo di un RTOS è quello di garantire la tempistica di ogni singolo task, mentre l’obiettivo di un sistema veloce è quello di minimizzare il tempo medio di risposta dei vari tasks; • Il tempo medio di risposta non può essere preso come un parametro significativo nel real-time. 3 Capitolo 1 Introduzione ai sistemi operativi real-time Si nota che per realizzare un valido sistema real-time, bisogna cercare di “emarginare”, nella maniera più efficace possibile, o quanto meno ridurre, le cause di indeterminismo che affliggono l’esecuzione di ogni singolo task. Queste ultime possono essere di diversa natura: 1. Architetturiale - Cache, pipelining, interruptus, DMA; 2. Operativo - Scheduling, sincronizzazione, comunicazione; 3. Linguaggio - Non hanno esplicito supporto per il tempo; 4. Metodologie progettuali - Mancanza di tecniche di analisi e verifica. Pertanto dopo aver fatto tali premesse introduttive, osservando la figura 2 che mostra una scala gerarchica dei sistemi operativi, possiamo inquadrare meglio gli RTOS all’interno della grande famiglia degli OS: Fig. 2 – RTOS all’interno della scala gerarchica dei OS 4 Capitolo 1 Introduzione ai sistemi operativi real-time Dall’osservazione della figura si nota come i sistemi operativi vengano di solito classificati in due grandi divisioni: i cosiddètti sistemi operativi a “scopo generale”(General Purpose) e quelli “specifici” (Special purpose). Questi ultimi poi, vengono a loro volta suddivisi in Embedded e Real Time. I primi, sono particolari OS di un elaboratore che spesso non ha tastiera, mouse, forse neanche uno schermo; ha comunque delle periferiche di I/O anche se non sono quelle canoniche ma sono architetture di calcolatori diffuse in ambiente industriale e biomedico. Tipicamente per questi particolari OS la memoria di massa non è un disco fisso bensì una memoria flash. Un sistema Embedded in altre parole, è un sistema “speciale” che deve solo assolvere il compito specifico per cui è stato programmato, per tale motivo tutti i sistemi Real-time possono essere considerati Embedded ma non viceversa (a causa dell’hardware profondamente diverso come detto, e dell’ OS). I sistemi real-time invece, come ribadito sopra, devono soddisfare precisi vincoli temporali per quel che concerne l’esecuzione dei propri tasks e devono essere caratterizzati non dalla velocità di esecuzione (parametro insignificante per il real-time), ma dalla “predicibilità” in quanto real-time non è sinonimo di “veloce” ma di “predicibile”. Quindi, constatato che il requisito fondamentale di questi sistemi è la “predicibilità”, è conveniente talvolta esprimere tale parametro di riferimento in funzione di un altro parametro altresì importante e ad esso strettamente correlato, ovvero il “determinismo”. Come si osserva dalla figura 3, la predicibilità è legata al determinismo da un legame di proporzionalità diretta, o meglio, all’aumentare dell’una aumenta l’altra in maniera del tutto proporzionale. Fig. 3 – Predicibilità in funzione del determinismo in un RTOS 5 Capitolo 1 Introduzione ai sistemi operativi real-time Essendo il requisito di predicibilità correlato fortemente alla scelta dello scheduler per il OS considerato, da un’analisi superficiale potrebbe risultare che solamente scheduler ciclici garantirebbero un alto valore di predicibilità, ma come si vedrà in seguito non sarà affatto così. In particolar modo, come mostrato dalla figura sottostante (figura 4), la scelta di uno scheduler diverso da quello ciclico, garantisce ancora predicibilità. Fig. 4 – Valutazione della predicibilità in base alla scelta della tipologia di scheduler Si evince facilmente, quindi, come la predicibilità sia un requisito di correttezza per applicazioni real-time ed il livello richiesto per codesto requisito è descritto solitamente nel documento di specifica dei requisiti del software. 6 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time 2.1 Introduzione Per un’analisi più prolifica delle numerose famiglie di RTOS è opportuno scindere il problema alla base diversificando anzitutto almeno due tipologie implementative: • Sistemi RTOS progettati appositamente che non si basano su OS già esistenti sul mercato; • Sistemi RTOS ottenuti mediante l’adattamento di OS originari già esistenti sul mercato; E’ da premettere che per la realizzazione di questo elaborato si farà riferimento quasi esclusivamente a sistemi RTOS ottenuti implementando sistemi operativi già esistenti sul mercato, ed in particolar modo a sistemi derivanti dalla piattaforma Linux consentendo quest’ultima risorse di tipo “Open Source” ed un ottima documentazione di base. 2.2 Caratteristiche strutturali di Linux OS E’ interessante notare in particolar modo, come si passi da una piattaforma Linux non real-time ad una piattaforma specificatamente RTOS implementata su quest’ultima. Per far ciò, ovviamente, è necessario analizzare le caratteristiche di Linux OS, già nella sua versione base e proprio a partire dallo scheduler, cercando di rilevare già in esso caratteristiche, o perlomeno spiragli, che aprano al real-time. A tal proposito osservando la figura 5 è possibile notare le diverse tipologie di scelta di scheduler e la conseguente 7 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time natura più o meno real-time dei tasks analizzati. Si rileva chiaramente come scheduler FIFO o di impostazione ROUND-ROBIN presentando una politica a priorità statica producano essenzialmente un’analisi predicibile dei tasks, contrariamente ad altri scheduler che adottando politiche di programmazione a priorità dinamica sono adatti sostanzialmente per tasks ordinari. In particolar modo, la politica del Time-sharing letteralmente “uccide” il real-time perché in quest’ultimo il tempo di esecuzione deve essere conosciuto a priori, mentre in Time-sharing non è affatto predicibile. Fig. 5 – Linux scheduling Tuttavia anche se solo lo scheduler di un sistema operativo tradizionale come il Linux sia più o meno orientato verso il real-time, ci possono essere problematiche di ben altra natura nel realizzare un RTOS. Qui di seguito sono esposte a titolo di esempio solo alcune tra le problematiche più evidenti che si incontrerebbero nell’implementazione di Linux in real-time(dati relativi al kernel 2.4): • Lo scheduler di Linux ha un taglio “general purpose”.Ciò sostanzialmente è fatto per distribuire equamente le risorse ai tasks in esecuzione; 8 Capitolo 2 • Passaggio dagli OS ai sistemi operativi di natura real-time Attualmente Linux non fornisce alcuna interfaccia per comunicare allo scheduler la possibile natura real-time di un task o dati specifici circa il suo timing (deadlines, computational times…); • Il kernel non è preemptable (ciò significa sostanzialmente alta latenza di scheduling per scenari real time); • Kernel Control Path non interrompibili( ma piuttosto reentrant, quindi annidabili) introducono in determinismo nel sistema; • Kernel non ancora 100% reentrant(alcune funzioni disabilitano gli interrupt globalmente sulla CPU corrente per preservare strutture dati condivise). Tali funzioni sono interrompibili solo attraverso un NMI; • La frequenza massima di richiamo della schedule() di Linux è 10ms(corrispondente al minimo time-quantum) che non risulta sufficiente per scenari real-time e oltretutto non vi è alcuna garanzia su tale periodo. Un altro fattore, non secondario ai precedenti, di cui bisogna sicuramente tener conto è poi la cosiddètta latenza di scheduler in Linux. Essa è definita come la distanza temporale tra il segnale (stimolo) di wakeup che un evento è accaduto e l’istante in cui lo scheduter lancia il thread che è in attesa che quel segnale arrivi (risposta). La latenza di scheduler è solo una delle possibili cause che affliggono le performance di un sistema operativo, in particolar modo essa influenza un parametro di confronto degli OS tradizionali, ovvero il tempo medio di risposta. Questo parametro, è significativo ovviamente solo per i sistemi operativi tradizionali, in quanto per le piattaforme realtime ci sono da soddisfare vincoli temporali su ciascun task e non interessa quindi la media di questi. Nella figura seguente (figura 6) vengono riportate le cause che influenzano, e quelle che contrariamente riducono, il tempo di risposta di un sistema: 9 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time Fig. 6 – Cause che agiscono sul tempo di risposta di un sistema Seguendo appunto i consigli descritti nella precedente figura, ossia ridurre il tempo di risposta introducendo percorsi privilegiati di prelazione e/o percorsi a bassa latenza, si è poi realizzata la versione più recente di Linux ovvero il Kernel 2.6, che mostra sicuramente un’apertura più evidente verso il real-time rispetto le precedenti versioni: • Modifica della struttura generale dello scheduler (ad esempio, invece di un’unica coda per tutti i task del sistema esiste una coda per ognuno dei 140 livelli di priorità su ogni CPU); • Frequenza interna del clock portata da 100 Hz (kernel 2.4) a 1000 Hz; • Parte del kernel è divenuta preemptable; • Eliminati numerosi “Big Locks”; • Compatibilità con Preemption e Low Latency Patches; • Migliorato il sistema di gestione di I/O. Effettuando quindi dei simili accorgimenti, si hanno ovviamente dei miglioramenti sull’analisi del tempo di risposta di un OS, miglioramenti che sono facilmente 10 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time osservabili analizzando la figura 7 dove una piattaforma Linux 2.6.9 viene confrontata rispettivamente senza e con preemption patch. Fig. 7 – Analisi del tempo di risposta senza e con preemption patch Quindi già nel passare ad una versione recente di Linux, come il Kernel 2.6 appunto, che sostanzialmente non ha come fine una politica real-time, bensì un ottimizzazione della versione precedente tradizionale, si hanno notevoli benefici di cui uno tra tutti è il tempo di risposta appena esposto. 2.3 Predisposizione di Linux ad una politica real-time Diversi benefici, su altri parametri (quali ad esempio la somma pesata dei tempi di completamento, la latenza massima ed il massimo numero di tasks ritardati), si possono ottenere invece mediante l’implementazione real-time della piattaforma Linux tradizionale. Una tale implementazione può essere realizzata facilmente a causa di alcune caratteristiche intrinseche del sistema sopra menzionato che ne permettono la modifica, l’implementazione, e che soprattutto ne agevolano l’apertura al real-time. Tali caratteristiche proprie del sistema operativo Linux che lo predispongono al real-time sono: 11 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time • Linux è un sistema operativo di alto livello ed è Open Source; • E’ molto ben documentato; • Nasce nell’ambiente universitario ed è naturalmente inserito in svariati contesti di ricerca; • E’ compatibile con i maggiori standard relativi al software (POSIX etc…); • Ha buone prestazioni già in versioni base (senza modifiche strutturali); • La struttura monolitica lo rende adatto ad essere utilizzato in scenari Embedded; • Il mondo dell’industria è interessato ad applicazioni di Linux in svariati settori: GPS (Global Positioning System), HDTV (High Definition TV), DVB-RCS, cellulari, PDA, space segment, signal processing, radar system, robotica… • Sono attualmente disponibili numerose implementazioni di architetture software Open Source per modificare Linux dotandolo di funzionalità realtime da cui attingere spunto… Constatata quindi la predisposizione di Linux a questa nuove politica di analisi dei tasks, solitamente sono due gli approcci che vengono seguiti per risolvere le problematiche relative al real-time in Linux (figura 8) : 12 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time Fig. 8 – Strategie per il real-time in Linux Il primo approccio è caratterizzato dal fatto che lo scheduler classico del Linux è sostituito per gran parte dal Preemptable Kernel che garantisce prelazione abbassando quindi il tempo di risposta. Il secondo approccio invece, conserva ancora il kernel del Linux tradizionale che viene però gestito da un apposito Resource Kernel come un task a bassa priorità. Il secondo approccio secondo molti studiosi è preferibile perché offrirebbe un architettura più snella non a caso, come vedremo, sarà il più adottato nelle implementazioni di Linux in real-time. 2.4 Panoramica dei sistemi operativi real-time presenti sul mercato Vediamo ora quali sono le distribuzioni real-time di Linux attualmente presenti sul mercato, ma prima di far ciò, per ragioni di chiarezza e di una migliore analisi del problema, è opportuno scindere le versioni real-time commerciali da quelle real-time Open Source che costituiranno parte integrante di questo elaborato essendo facilmente documentabili. 13 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time 2.4.1 Distribuzioni real-time commerciali Le attuali distribuzioni real-time commerciali di Linux che si trovano oggigiorno sul mercato informatico sono le seguenti: • RTLinuxPro(FSMLabs). RTCore fornisce un ambiente real-time POSIX in cui Linux gira come task a bassa priorità. Limiti prestazionali: quelli dell’ hardware. Latenza di scheduling sotto 20 microsecondi sulla maggior parte delle piattaforme. • MontaVista RTLinux. Basato su miglioramenti a MontaVista Linux. Preemptable kernel + real-time scheduler + frameworks. • BlueCat RT (LynuxWorks). Microsistema operativo real-time (non Linux-based) che gira Linux come processo a bassa priorità. BlueCat RT è incentrato sulle basse latenze di interrupt raggiunte grazie al core ridottissimo e altamente performante. • uLinux (Lineo Solutions). Footprint ridottissimo, tempi di startup e shutdown minimi, prestazioni real-time rendono adatto questo OS made in Japan per l’utilizzo nell’elettronica (dispositivi embedded). • FlightLinux (NASA). Versione real-time di Linux adattata ad applicazioni spaziali al Goddard Space Flight Center e testata sullo Space Shuttle (progetto nato come Open Source ma i sorgenti non sono attualmente pubblicati). 14 Capitolo 2 Passaggio dagli OS ai sistemi operativi di natura real-time 2.4.2 Distribuzioni real-time open source Per quel che concerne invece le distribuzioni real-time di Linux di tipo Open Source, ecco riportata di seguito qual è la situazione attuale: • RTLinux. Hard Real Time mini sistema operativo che gira Linux come processo a minima priorità rendendolo totalmente preemptable. L’ultima versione supporta user-space RT programming. La versione MiniRTL è adatta ad utilizzi embedded. • RTAI (Dipartimento di Ingegneria Aerospaziale del Politecnico di Milano). Simile ad RTLinux ma con varie funzionalità in più tra cui LXRT Layer che permette di controllare task real-time dallo user-space memory-protected di Linux . AtomicRTAI è la versione a ridotto footprint. • KURT. The Kansas University RealTime Linux. Implementazione real-time di Linux che permette lo scheduling degli eventi con periodo di 10 microsecondi. • RED-Linux. Ridotti kernel blocking times, rapidi tempi di risposta, scheduler modularizzato “modificabile” a runtime. Università della California, Irvine. • QLinux. Implementazione tagliata per garantire caratteristiche di QoS per task soft real-time. Tagliata per l’utilizzo in applicazioni multimediali, telefonia mobile… 15 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato: RTLinux ed RTAI 3.1 Introduzione Nel campo dei sistemi operativi real-time, i più diffusi ed implementati sono senza dubbio la versione real-time base di Linux (RT-LINUX) e quella implementata dal Dipartimento di Ingegneria Aerospaziale del Politecnico di Milano (RTAI). Queste, essendo state studiate per prime, sono le più documentate e forniscono funzionalità aggiuntive nonché innovative ad un sistema come Linux che se pur predisposto non presenta caratteristiche real-time (come Windows d’altronde). Qui di seguito verranno analizzate queste due note piattaforme dapprima singolarmente, e poi successivamente assieme, al fine di permetterne un più rapido confronto. 3.2 RTLinux 3.2.1 Un’introduzione ad RTLinux RT-Linux è un sistema operativo nel quale un piccolo kernel real-time coesiste con il kernel di Linux (like-POSIX). L’intenzione è quella di fare uso dei servizi sofisticati ed altamente ottimizzati (per quel che concerne il comportamento medio) di un sistema di computer standard a time-shared, mentre ancora si permette alle funzioni real-time di operare in un ambiente predicibile ed a bassa latenza. Inizialmente i sistemi operativi real-time erano essenzialmente primitivi: semplici esecuzioni che facevano poco più che offrire una libreria di routines. Ma le applicazioni real-time di oggi richiedono 16 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI abitudinariamente accesso al TCP/IP, display grafico e sistemi windowing, files e sistemi data-base, ed altri sistemi che non sono né primitivi né affatto semplici. Una soluzione è quella di aggiungere questi servizi non real-time al kernel real-time di base, come d’altronde è stato fatto per il noto VxWorks ed, in maniera differente, per il microkernel QNX. Una seconda soluzione, è invece quella di modificare un kernel standard al fine di renderlo completamente prelazionabile. Questo è appunto l’approccio intrapreso dagli sviluppatori di RT-IX. RT-Linux è basato invece su una terza corrente di pensiero nella quale una semplice esecuzione real-time viene eseguita su un kernel non real-time come se fosse il suo task a più bassa priorità, utilizzando un livello di virtual-machine per rendere il kernel standard completamente prelazionabile. In RT-Linux tutti gli interrupts sono inizialmente gestiti dal kernel real-time e sono trasferiti al task di Linux solo quando non ci sono tasks real-time da eseguire. Per minimizzare i cambiamenti nel kernel di Linux, esso è fornito di un hardware che emula il controllo degli interruptus. Pertanto, quando Linux ha “disabilitato” gli interrupts, il software emulativo accoderà gli interrupts che gli sono stati passati dal kernel real-time. Gli user tasks di Linux e quelli real-time comunicano attraverso code lock-free o memoria condivisa all’interno del sistema corrente. Dal punto di vista applicativo dei programmatori, le code sembrano molto simili ai dispositivi a carattere di UNIX standard, che possono essere acceduti per mezzo di system calls POSIX di tipo read/write/open/ioctl. L’accesso alla memoria condivisa viene correntemente regolato mediante le chiamate alla funzione POSIX mmap. RT-Linux rilascia su Linux, per permetterne il riavvio, la maggior parte dei drivers del dispositivo, il networking, i file systems, il controllo dei processi di Linux, ed i moduli caricabili del kernel che sono utilizzati per rendere il sistema real-time estensibile e più facilmente modificabile. Le applicazioni real-time consistono in tasks real-time che sono incorporati in moduli caricabili del kernel ed in processi di Linux/Unix che si occupano dei registri dati, del display, dell’accesso alla rete, e di altre funzioni che non sono vincolate da una caratterizzazione del comportamento nel caso peggiore (worst case). In pratica, l’approccio ad RT-Linux ha avuto molto successo in quanto si è dimostrato essere un approccio vincente. La latenza di interrupt nel caso peggiore su un PC 486 a 33 MHz si assesta ben sotto i 30 µs, vicino al limite dell’hardware. Molte applicazioni sembrano trarre beneficio da una “sinergia” tra il sistema real-time ed il sistema operativo standard ottimizzato (average case). Per esempio, le applicazioni di 17 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI acquisizione dati sono spesso composte da un semplice polling o un task real-time di tipo interrupt-driven che conduce i dati attraverso una coda al processo Linux che si occupa di gestire il logging ed il display. In alcuni casi, l’attività di buffering dell’I/O e l’aggregazione eseguita da Linux, forniscono un alto livello di performance del caso medio mentre il task real-time incontra tassative deadlines limitate al caso peggiore. RT-Linux può essere considerato un sistema operativo sia spartano che estensibile in accordo rispettivamente con due tipologie di progetto piuttosto contraddittorie tra loro. La prima tipologia progettuale, in realtà sostiene che i componenti che devono sottostare a vincoli temporali di un’applicazione real-time non sono compatibili con l’allocazione dinamica delle risorse, né con una sincronizzazione complessa, e nè con qualcos’altro che introduca sia costi hard che particolarmente significanti per limitare i ritardi. La configurazione più largamente utilizzata di RT-Linux offre tasks primitivi con memoria allocata solo staticamente, nessuna protezione per lo spazio degli indirizzi, un semplice scheduler a priorità fissa che non presenta alcuna protezione verso gli schedules impossibili. Consente, inoltre, di disabilitare gli interrupt hard e presenta una memoria condivisa con le sole primitive di sincronizzazione tra i tasks real-time ed un range limitato di operazioni sulle code FIFO che connettono i tasks real-time ad i processi Linux. L’ambiente non è davvero così austero come potrebbe sembrare, poiché la ricca collezione di servizi forniti dal kernel non real-time sono facilmente accessibili dagli user-tasks di Linux. I componenti non real-time delle applicazioni si spostano verso Linux. Un’area dove si spera di fare un uso particolare di questo paradigma è nel QOS, dove sembra ragionevole fattorizzare le operazioni in componenti hard real-time che raccolgono o distribuiscono dati sensibili alle variazioni temporali (time sensitive), ed in processi Linux o threads che osservano data rates, negoziano per il tempo necessario al processo e regolano gli algoritmi. La seconda tipologia di progetto, per quel poco che si sa, si preoccupa di come i sistemi real-time dovrebbero essere organizzati e di come i sistemi operativi dovrebbero allocare, per una maggiore flessibilità,cose del genere come le caratteristiche dei tasks real-time, la comunicazione e la sincronizzazione. Il kernel è stato progettato con moduli sostituibili pratici dovunque e l’ambiente spartano descritto nelle righe precedenti è stato facilmente “migliorato”. Ci sono oggigiorno moduli di scheduling alternativi, alcuni proposti ed introdotti dalle diverse comunità degli utenti, per permettere lo scheduling dei tasks con algoritmi EDF e Rate-Monotonic. Esistono anche un “modulo semaforico” ed uno sviluppo attivo di un set più ricco di servizi per il 18 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI sistema. Linux consente che questi servizi vengano offerti mediante i moduli caricabili del kernel così che l’operazione fondamentale del kernel real-time sia riconfigurabile a run-time (sebbene non sia rel-time). E’ possibile sviluppare un set di tasks sotto RTLinux, testare un sistema utilizzando uno schedule EDF, deallocare il modulo di scheduling di EDF, caricare un modulo di scheduling Rate-Monotonic, e continuare il test. Dovrebbe eventualmente essere possibile utilizzare un modello di processo a memoria protetta, al fine di testare differenti implementazioni di IPCs e di sondare diversamente il sistema finchè non viene trovato un giusto mix di servizi. 3.2.2 Un’aggiunta hard real-time a Linux RTLinux è un sistema operativo hard real-time che gira in Linux come il suo thread di esecuzione a più bassa priorità. Il thread di Linux è reso completamente prelazionabile così che i threads real-time ed i gestori di interrupts non possano venir mai ritardati da operazioni non real-time. I threads real-time in RTLinux possono comunicare con i processi Linux attraverso una memoria condivisa oppure mediante una particolare interfaccia simile ad un file, in tal modo le applicazioni real-time possono far uso di tutti i potenti servizi non real-time di Linux. Per esempio è piuttosto semplice comporre uno script che visualizzi dati in Xwindows, risponda a comandi trasmessi da rete e collezioni dati da un task real-time. RTLinux supporta gestori di interrupt real-time e tasks periodici real-time con latenze di interrupt e jitters di scheduling molto vicine ai limiti dell’hardware. Si pensi che la latenza di interrupt nel caso peggiore su un modesto PC x86 appropriatamente configurato si mantiene sotto i 15 µs dal momento in cui l’interrupt viene servito dall’hardware. Configurazioni migliori dell’ hardware producono certamente tempistiche migliori. L’esempio descritto precedentemente fa riferimento ovviamente allo scenario del worst case (e non ad uno scenario tipico), dove il tempo viene calcolato dall’istante in cui l’hardware serve l’interrupt e non quando lo scheduler del sistema operativo è in esecuzione. I tasks real-time in RTLinux, come già detto precedentemente, possono comunicare con i processi Linux attraverso una memoria condivisa oppure mediante una particolare interfaccia file-like, quindi le applicazioni real-time possono fare uso di tutte le caratteristiche (non real-time) proprie del sistema operativo Linux, incluse: 19 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI • Networking; • Grafica; • Sistemi Windowing; • Packages per l’analisi dei dati; • Drivers per Linux; • Standard POSIX API. Tre versioni di RTLinux sono disponibili oggi via ftp: • RTLinux V1. Si tratta di un sistema eccezionalmente stabile che viene utilizzato sia in prodotti commerciale che in ambienti di laboratorio. Fornisce inoltre una semplice libreria API per eseguire, iniziare, e fermare lo scheduling dei tasks real-time. • RTLinux V2. Offre una versione semplificata dell’ API dei pthreads POSIX ed è conforme allo standard “Minimal Real-time” di POSIX (all’interno del quale un componente real-time è considerato un processo POSIX singolo e multithread). L’obiettivo del kernel V2 è senza dubbio quello di accostarsi il più possibile allo standard POSIX, senza attuare alcun sacrificio dal punto di vista della semplicità e velocità del sistema, ma al tempo stesso fornendo spunti ed aggiunte per realizzare una piena compatibilità con POSIX. V2, messo sul mercato nel Novembre del 1999, è un sistema x86 capace di SMP. • RTLinux V3 Beta. E’ stato immesso sul mercato il 3 Gennaio del 2000 e rispetto alle precedenti versioni essa aggiunge il supporto PowerPC. RTLinux, sviluppato originariamente nell’Istituto di Tecnologia del New Mexico, si pone in commercio come un prodotto “open-source”. Componenti specifici di RTLinux vengono rilasciati sotto licenza GPL, mentre i componenti di Linux vengono rilasciati sotto la licenza di Linux standard. Il codice sorgente viene liberamente distribuito. Le versioni non a licenza GPL dei componenti di RTLinux sono disponibili tramite gli FSMLabs. 20 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI . 3.3 RTAI 3.3.1 Premessa Prima di vedere le caratteristiche salienti di questo sistema operativo, è bene tuttavia fare una premessa importante sul real-time. Nel capitolo 1 si erano introdotte infatti le caratteristiche peculiari del real-time, mentre nel capitolo 2 la predisposizione di Linux ad una politica siffatta. Ora, invece, si discuterà sui possibili significati del termine “real-time” e su come i relativi standards Linux siano appropriati per implementare una tale politica. Il termine “real-time” può avere differenti significati dipendenti sostanzialmente dal tipo e dalla natura dell’applicazione in questione. Comunque, la letteratura informatica generalmente definisce solo due tipi: i sistemi “soft”e quelli “hard” real-time. Un sistema “soft real-time” è caratterizzato dalla capacità di analizzare la performance di un task che, mediamente, è eseguito secondo le schedule desiderato. Un display video è un buon esempio, dove lo sforamento della deadline da parte di un frame occasionale non causerà alcuna degradazione percettibile del sistema, facendo in modo che la performance media resti tuttavia accettabile. Sebbene tecniche come l’interpolazione possano essere usate per compensare i frames sforanti, il sistema rimane pur sempre un sistema “soft real-time” poiché il dato attuale è perso ed il frame interpolato rappresenta una dato derivato piuttosto che un dato attuale. I sistemi “hard real-time” sono invece sistemi “tempo-garantiti” pertanto non possono sforare deadlines temporali e devono avere latenze limitate. Dal momento che le deadlines non possono essere mai sforate, un sistema hard real-time non può usare la performance del caso medio per compensare la relativa performance del caso peggiore. Un esempio di un task hard real-time potrebbe essere dato dai trasduttori di monitoraggio in un reattore nucleare, i quali devono usare un complesso sistema di controllo digitale in maniera da evitare pesanti disastri. RTAI fornisce a Linux queste necessarie estensioni hard real-time, consentendogli quindi di essere adatto anche ad applicazioni dove le deadlines temporali non possono essere sforate. 21 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.3.2 Regole per il supporto real-time al kernel di Linux RTAI permette estensioni hard real-time al kernel di Linux, eppure lo standard Linux supporta le estensioni real-time POSIX 1003.13, pertanto nasce implicita la domanda su come venga meno la capacità real-time dello standard Linux. Lo standard POSIX 1003.13 definisce sostanzialmente un “profilo del sistema rea-time multi-utente” che permette ai processi “real-time” di essere conservati in memoria per impedirgli di essere paginati sull’hard disk, ed uno scheduler speciale che assicura che questi processi vengano sempre eseguiti in maniera predicibile. Linux si avvicina a questo standard offrendo una serie di servizi aggiuntivi come: il POSIX-compliant memory-lock (mlock); uno schedule speciale (sched_setsched); system call e segnali RT POSIX. Sebbene queste caratteristiche offrano una prestazione deterministica migliore, i tasks risultanti non possono essere definiti come tasks hard real-time, dal momento che il processo soft real-time può essere bloccato dall’attività del kernel. Pertando essendo Linux non hard real-time (ma di tipo “general-purpose”) le sue esigenze saranno quindi differenti da quelle di un sistema operativo di tipo hard real-time. Ciò porta ad una serie di regole, sotto riassunte, che limitano il potenziale del Linux standard ad agire come un sistema operativo real-time. • Il kernel di Linux usa una sincronizzazione granulata e spessa che consente ad un task del kernel l’accesso esclusivo ad alcuni dati per un lungo periodo. Ciò però ritarda l’esecuzione di alcuni tasks real-time POSIX che necessitano l’accesso a quegli stessi dati; • Linux non prelaziona l’esecuzione di alcun task durante le system calls. Se un processo a bassa priorità è al centro di una system call “fork” e viene ricevuto un messaggio per un processo del display video, allora il messaggio sarà sfortunatamente trattenuto nella coda finchè la call non sarà completata, nonostante la sua bassa priorità. La soluzione sarebbe quella di aggiungere punti di prelazione nel kernel producendo di contro effetti deleteri per le system call; 22 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI • Linux permette che i tasks ad alta priorità aspettino il rilascio delle risorse da parte dei tasks a bassa priorità. Per esempio, se un processo alloca l’ultimo buffer di rete, ed un processo a più alta priorità del precedente necessita del buffer di rete per mandare un messaggio, questo deve attendere che l’altro processo gli rilasci la risorsa per spedire il suo messaggio; • L’algoritmo di scheduling di Linux qualche volta darà un “time-slice” al processo meno importante e che è in attesa da più tempo (“nicest”), persino in circostanze in cui è eseguibile un processo ad alta priorità. Ciò è una caratteristica propria di un sistema operativo “generalpurpose” che assicura il mantenimento e quindi l’esecuzione di processi in background; • Linux riordina le richieste dei processi multipli al fine di utilizzare più efficientemente l’hardware. Per esempio il blocco dell’hard-disk che legge da un processo a più bassa priorità, potrebbe avere la precedenza su richieste di lettura effettuate da un processo a più alta priorità in maniera da minimizzare il movimento dalla testa del disco e migliorare le possibilità di recupero dell’errore; • Linux ingloba(batch) operazioni per utilizzare l’hardware sottostante più efficientemente; Per esempio invece di liberare una pagina nel momento in cui la memoria è bloccata, Linux allocherà le sue pagine libere seguendo la lista delle pagine, operazione che ritarderà ovviamente l’esecuzione di tutti i processi. Ciò è chiaramente desiderabile per un sistema “general-purpose” ed al tempo stesso ovviamente non desiderabile per processi real-time. Come si evince da tali regole i sistemi “real-time” e quelli “general-purpose” hanno esigenze progettuali profondamente diverse tra loro, talvolta addirittura contraddittorie: un effetto desiderabile in un sistema è spesso deleterio nell’altro. Sfortunatamente 23 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI alcuni tentativi di soddisfare entrambe le esigenze nello stesso kernel spesso produce un sistema che non fa bene nessuna delle due. Non si può affermare però che le funzionalità “general-purpose” ed il determinismo “real-time” non possano essere implementate simultaneamente. Infatti, oggigiorno nel mercato informatico esistono sistemi operativi che combinano entrambe queste esigenze ed essi sono in effetti deterministici, prelazionabili e contengono latenze limitate (pertanto incontrano le esigenze di un sistema hard real-time). Comunque, il comportamento nel caso peggiore di queste latenze può essere inaccettabile. 3.3.3 Un’introduzione ad RTAI Al fine di rendere Linux utilizzabile per applicazioni hard real-time, i membri del Dipartimento di Ingegneria Aerospaziale del Politecnico di Milano (DIAPM) crearono un livello di astrazione hardware real-time (RTHAL) sul quale poter implementare un interfaccia per applicazioni real-time RTAI. Sfortunatamente, ulteriori indagini rivelarono che il kernel di Linux disponibile nel vicino 1996, ovvero il 2.0.25, non era ancora pronto ad accogliere tale innovazione. Nello stesso periodo, un gruppo capeggiato da Victor Yodaiken all’Istituto del New Mexico of Minino and Technology (NMT) , introdusse la sua versione real-time di Linux (RTLinux) che fornì al team DIAPM l’opportunità di apprendere ulteriori nozioni sul kernel di Linux, sull’ hardware e sulle modifiche necessarie a rendere prelazionabile e deterministico lo scheduling. Il punto di svolta ci fu poi nel 1998 quando fu sviluppato il kernel di Linux 2.2.x che ebbe come punto di forza i noti miglioramenti proposti dall’RTLinux, incluso le molte e necessarie modifiche architetturiali all’interfaccia Linux/hardware. Tali modifiche, combinate con l’esperienza acquisita dal team DIAPM durante il loro lavoro di evoluzione dell’NMTRTLinux kernel, e con le nozioni informatiche del 1996, sfociarono nella creazione della piattaforma RTAI. RTAI è un sistema operativo “guaranteed-based” che assicura uno scheduling hard real-time ed inoltre conserva tutte le caratteristiche ed i servizi del Linux standard. In aggiunta, RTAI fornisce un supporto sia per UP che per SMP con la capacità di assegnare sia tasks che IRQs alle specifiche CPUs, x486 e Pentiums, schedulers oneshot e periodici, sia inter-Linux che intra-Linux shared memory, compatibilità con lo 24 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI standard POSIX, supporto FPU, sincronizzazione tra tasks, semafori, sincronizzazione mutua, code per messaggi, RPCs, mailboxes, la possibilità di utilizzare le system call RTAI direttamente da dentro lo user-space standard, e tante altre funzionalità. Oggigiorno sono presenti molteplici versioni di questa piattaforma (si osservi a tal proposito la figura 9), versioni che solitamente vengono classificate “Stabili”, da “Testing”, di “Sviluppo” e “Sperimentali”. Fig. 9 – RTAI : Versioni 3.3.4 L’architettura RTAI L’architettura di base dell’RTAI è abbastanza simile a quella dell’RTLinux come mostrato in figura 10. 25 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Fig. 10 – RTAI : Schema architetturiale Per ogni implementazione, il sistema operativo Linux è eseguito come il task a più bassa priorità di un piccolo sistema operativo real-time. Pertanto Linux non apporta cambiamenti alle sue operazioni sia dal punto di vista utente che dal punto di vista kernel, eccetto quello di permettere l’esecuzione solo quando non ci sono già tasks realtime che devono essere eseguiti. Dal punto di vista funzionale, entrambe le architetture presentano la capacità di eseguire speciali tasks real-time e gestori di interrupt ogni volta che sono necessari, senza tener conto di come altri tasks di Linux possano venire eseguiti. Entrambe le implementazioni estendono l’ambiente standard di programmazione Linux ai problemi del real-time presentando al loro interno appunto tasks real-time e gestori di interruptus per comunicare attraverso i processi Linux tradizionali attraverso un’interfaccia propria del dispositivo o talvolta anche mediante memoria condivisa. La prima differenza architetturiale che si scorge osservando le due implementazioni, sta in come queste caratteristiche real-time vengono aggiunte alla piattaforma Linux tradizionale. Sia RTLinux che RTAI approfittano del fatto che i moduli del kernel di Linux siano caricabili per implementare facilmente servizi realtime. Comunque, una delle differenze “chiave” tra le due sta in come queste modifiche, al fine di aggiungere estensioni propriamente real-time, siano applicate al kernel standard dil Linux. 26 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI RTLinux applica molti cambiamenti ai file di source del kernel che si manifestano in modifiche ed aggiunte ai numerosissimi files sorgenti del kernel di Linux. Quindi, viene aumentata sostanzialmente “l’investigazione” dei files sorgenti del kernel di Linux, che conduce ad un conseguente aumento del codice da memorizzare, ed inoltre permette gli aggiornamenti ed i cambiamenti del kernel e rileva virus più difficili da trovare. RTAI riduce i cambiamenti al kernel standard di Linux mediante l’aggiunta di un livello di astrazione hardware (HAL) composto da una struttura di puntatori a vettori di interrupt e da funzioni che permettono di abilitare/disabilitare gli interruptus (figura 11). Fig. 11 – RTAI : Architettura interna L’HAL viene implementato modificando meno di 20 linee di codice esistente, ed aggiungendo circa 50 linee di nuovo codice. Questo approccio è sicuramente più elegante in quanto minimizza l’investigazione del kernel standard di Linux e localizza più facilmente il codice di gestione degli interrupt. Un altro vantaggio della tecnica HAL è che mediante essa è possibile far tornare Linux al suo ruolo standard (generalpurpose) cambiando semplicemente la posizione dei suoi puntatori dalla struttura RTHAL (real-time) a quella originale. Ciò si è dimostrato abbastanza utile quando le operazioni real-time sono inattive o quando si prova ad isolare virus di natura oscura. E’ importante sottolineare come lo strato HAL sia alla base delle struttura di RTAI, esso infatti rappresenta il livello più basso di tale architettura che lavorando con i livelli sovrastanti (figura 12 ) riesce a fornire alla piattaforma caratteristiche real-time. 27 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Fig. 12 – Struttura completa di RTAI Molti studiosi suppongono che il livello HAL possa causare inaccettabili ritardi e latenze per via del percorso di analisi e monitoraggio dei tasks real-time. In realtà negli ultimi anni l’impatto dell’HAL sulle performances del kernel è divenuto trascurabile per via della maturità e del progetto del kernel di Linux e soprattutto per via di coloro che hanno contribuito al suo sviluppo. 3.3.5 Real-time application interface RTAI supporta ben 5 moduli caricabili del core che conferiscono al sistema le proprietà real-time desiderate “a richiesta”(on-demand). Queti moduli includono: rtai, che fornisce la struttura base rtai; rtai_sched, che fornisce al sistema uno scheduling oneshot oppure periodico; rtai_mups, che consente l’uso simultaneo degli schedulers oneshot e periodico oppure di due schedulers periodici, ognuno avente il proprio clock di base differente; rtai_shm, che alloca la memoria propria di inter-Linux tra i tasks realtime ed i tradizionali processi di Linux, ed anche intra-Linux come sostituto per UNIX V IPC; ed rtai_fifos, che altro non è che un adattamento di NMT RTLinux FIFOs (file in, file out). Come tutti i moduli del kernel, questi possono essere caricati in memoria e deallocati da essa (usando rispettivamente i comandi standard di Linux insmod ed rmmod) quando le loro rispettive funzionalità sono richieste o meno. Per esempio per installare solo gestori di interruptus è necessario caricare solo il modulo rtai. Per comunicare invece con i 28 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI processi di Linux standard utilizzando FIFOs, allora sarebbe opportuno caricare i moduli rtai ed rtai fifos. Questa architettura modulare e certamente “non-intrusiva” (per il kernel del Linux standard), permette alle FIFO di poter essere eseguite su qualche coda e di utilizzare, se necessario, immediati wake-ups. 3.3.6 Il task real-time Il task real-time viene implementato allo stesso modo di RTAI; nel senso che viene scritto e compilato come un modulo del kernel che viene caricato all’interno del kernel dopo che è stato caricato a sua volta il modulo del core di RTAI richiesto. Questa architettura produce un sistema semplice e facilmente sostenibile che consente un’inserzione dinamica delle proprietà real-time desiderate e dei tasks. L’esempio riportato nelle righe seguenti mostra tutto ciò che è richiesto affinché un task sia schedulato in maniera real-time: insmod /home/rtai/rtai insmod /home/rtai/modules/rtai_fifo insmod /home/rtai/modules/rtai_sched insmod /path/rt_process Per fermare l’applicazione e rimuovere RTAI basta invece applicare i seguenti comandi: rmmod rt_process rmmod rtai_sched rmmod rtai_fifo rmmod rtai Le strutture idmod e remod possono essere utilizzate poi per allocare in memoria e deallocare i moduli del core. 29 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.3.7 Il task scheduler Il task scheduler di RTAI consente di realizzare l’hard real-time, ovvero uno scheduling completamente prelazionabile (full preemptive) basato su uno schema a priorità fissa. Tutti gli schedules possono infatti essere gestiti mediante funzioni temporali ed eventi real-time (come l’acquisizione semaforica, clocks, e gestori di eventi asincroni), includendo anche al loro interno la sincronizzazione inter-task. I principali schedulers di RTAI sono rappresentati nella figura sottostante (figura 13). Fig. 13 – Schedulers di RTAI 3.3.8 Scheduling one-shot e periodico RTAI, come già detto, supporta entrambi i timers one-shot e periodici sul Pentium e sulle CPUs 486-class (si osservi figura 14). 30 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Fig. 14 – Scheduling di RTAI Sebbene entrambi i timers siano supportati, essi potrebbero non essere istanziati simultaneamente, cioè potrebbero non essere caricati nel kernel come moduli nello stesso istante di tempo. Utilizzando questi timers (istanziati per mezzo di rtai_sched), è possibile supportare i rates periodici che eccedono di 90 kHz e che dipendono dalle CPU, dalla velocità del bus e dalle performances del chips. Su processori di tipo Pentium, sono supportati rates per task one-shot che eccedono di 30 kHz (Pentium II, 233 MHz), mentre su macchine 486 l’implementazione one-shot fornisce rates di circa 10 kHz tutto ciò mentre conserva in più abbastanza CPU time da servire il kernel di Linux standard. La limitazione di rtai_sched di supportare simulataneamente i timers one-shot e periodici, è mitigata dal MulitUniProcessor (MUP) real-time scheduler (rtai_mups), il quale fornisce la proprietà di utilizzare, simultaneamente, sia un timer periodico che one-shot o due timers periodici con differenti periodi, a delle performances equivalenti a quelle descritte sopra da rtai_sched. Si nota che dal momento che il MUP utilizza l’APIC (advanced programmable interrupt controller) timer, esso non può operare sotto SMP e richiede pertanto che ogni task scedulato MUP sia eseguito all’interno di una specifica CPU (da qui la designazione MultiUniProcessor). Comunque il MUP conserva tutte le coordinate ed i servizi IPC in modo che le altre proprietà non vengano perse. 31 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.3.9 Operazioni floating-point Le operazioni floating-point all’interno dei tasks real-time/ISRs (Interrupt service routines) sono possibili, esse permettono a questi task di essere contraddistinti nel loro caricamento come tasks che richiedono l’FPU. Questo metodo permette che i taks realtime possano accedere all’FPU mentre si sta ancora allocando l’accesso FPU ai tasks di Linux standard. 3.3.10 Interrupt handling RTAI fornisce un accesso efficiente ed immediato all’hardware allocando, se viene scelta, l’interazione direttamente con il basso livello hardware PC senza prima passare attraverso i livelli di gestione dell’interrupt propri del kernel di Linux standard. La capacità di assegnare individualmente specifiche IRQs a specifiche CPUs, come descritto con maggiore dettaglio sotto, fornisce all’hardware tempi di interfacciamento immediati, di pronta risposta, e soprattutto garantiti. 3.3.11 Inter-process communication Il termine inter-process communication (IPC) descrive differenti metodi di scambiare messaggi tra processi attivi o tasks, ed inoltre specifica anche numerose forme di sincronizzazione per attuare un trasferimento dati. Linux fornisce al sistema standard V IPC memoria condivisa, FIFOs, semafori, sincronizzazione mutua, variabili condizionali e pipes che possono essere usate dai processi utenti standard per trasferire e condividere dati. Sebbene questi meccanismi IPC di Linux non siano disponibili per creare tasks real-time, RTAI fornisce un set aggiuntivo di meccanismi IPC che includono a loro volta memoria condivisa, code per messaggi, real-time FIFOs, sincronizzazione mutua, semafori e variabili condizionali (figura 15). 32 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Fig. 15 – RTAI : Set di meccanismi IPC Tali meccanismi sono utilizzati per trasferire e condividere dati tra tasks e processi in entrambi i domini, ovvero sia in real-time che nello user-space di Linux. Il meccanismo di “remote procedure call” (RPC) proprio di RTAI è simile nelle operazioni ai messaggi QNX disponibili per i tasks real-time, e trasferisce sia un intero senza segno che un puntatore al task di destinazione. L’implementazione della mailbox di RTAI offre la possibilità di spedire messaggi dai task dello spazio utente a quelli real-time, da un task real-time ad un altro task real-time, tra due tasks dello spazio utente (utilizzando LXRT), semplicemente attraverso la definizione della dimensione del buffer della mailbox. Sono consentiti molteplici mittenti e molteplici riceventi, dove ognuno di essi viene servito secondo la sua priorità. 3.3.12 Proc-interface Dalla versione 0.9, RTAI include una “proc-interface” che da un’informazione utile sullo stato corrente di RTAI che include anche gli schedulers caricati in memoria, l’attività dei tasks real-time, la priorità ed il periodo, le FIFOs attualmente in uso e le loro associate dimensioni del buffer. Lo sviluppo di ulteriori caratteristiche in tale ambito è attualmente in fase di studio. 33 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.3.13 SMP support RTAI fornisce un supporto “reale” alle architetture symmetric multi.processing (SMP) attraverso la gestione dei suoi tasks e quella IRQ. Per default, tutti i tasks sono assegnati per essere eseguiti dalle CPUs di una piattaforma SMP. Ogni task, comunque, può essere individualmente assegnato ad un set di CPUs o persino ad una singola CPU. In aggiunta è possibile assegnare il servizio di interrupt real-time a qualche specifica CPU. Poiché la capacità di forzare un interrupt ad una specifica CPU non è propria dello scheduler SMP, RTAI conserva la flessibilità di ottimizzare queste due operazioni indipendentemente. Queste capacità forniscono un metodo di ottimizzazione statica dell’applicazione realtime, se la distribuzione manuale del task gestisce il task più efficientemente dei servizi automatici di load-distribution SMP di Linux. 3.3.14 Linux-RT(LXRT) Da quando i tasks di Linux real-time sono stati implementati come moduli caricabili, essi rappresentano, per tutti gli scopi pratici, una parte integrale del kernel. In quanto tali, questi tasks non sono limitati dai servizi di protezione della memoria propri di Linux, ed hanno la capacità di sovrascrivere aree critiche del sistema di memoria portando il sistema ad un arresto prematuro. Questa limitazione ha rappresentato una larga frustrazione per tutti i ricercatori che si sono imbattuti nello sviluppo dei tasks real-time. LXRT di RTAI risolve questo problema semplicemente consentendo lo sviluppo dei tasks real-time, utilizzando tutte le system calls hard real-time proprie di RTAI direttamente dall’interno dello spazio protetto di memoria di Linux e facendo pertanto uso di un servizio real-time “firm”. Non appena lo sviluppatore del sistema è soddisfatto delle performances del task all’interno di LXRT, il task viene semplicemente ricompilato come un modulo ed inserito all’interno del kernel (insieme con i moduli associati che provvedono a realizzare le caratteristiche real-time di RTAI) per permettere la transizione dal “firm” real-time all’“hard” real-time. Il servizio firm real-time di LXRT,in maniera simile a quello offerto dalla piattaforma Kansas University Real time (KURT), fornisce funzionalità soft real-time combinate 34 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI con un task scheduling fine-grained. Le prestazioni sotto LXRT sono abbastanza buone: le latenze diventano non molto più grandi di quelle relative alla system call di Linux standard che dirige una commutazione tra tasks. Sebbene questo abbia molto valore come tool di sviluppo, non bisogna perdere di vista il fatto che l’implementazione firm real-time di RTAI possa dimostrarsi specialmente utile per quei tasks che non richiedono hard real-time , ma che non son stati ancora soddisfatti dalla prestazione dello scheduling di Linux standard. 3.3.15 Posix compatibility API RTAI implementa un particolare set di istruzioni di POSIX 1003.1.c attraverso l’uso di un modulo caricabile singolarmente. Questo set richiama a sua volta la creazione di un supporto, la successiva cancellazione, il controllo degli attributi e dell’ambiente per i threads, la sincronizzazione mutua e le variabili di stato (figura 16). Fig. 16 – RTAI : Programmazione Il risultante supporto al POSIX diviene simile ai threads di Linux standard, eccetto che nelle funzioni parent-child (che non sono appropriate per i tasks real-time dal momento che tutti i threads vengono considerati far parte di un singolo processo) e nei gestori di segnali (che son attualmente in fase di sviluppo) che non sono ancora supportati. 35 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.3.16 Performances tipiche RTAI è oggigiorno competitivo, sia da un punto di vista economico che da una prospettiva strettamente prestazionale, rispetto ai sistemi operativi real-time (RTOS) attualmente disponibili in commercio. Dal momento che le prestazioni dei sistemi RTOS sono determinate dalle performances degli RTOS stessi, dalle prestazioni dell’hardware sul quale esso “gira”, e dalle procedure di test utilizzate per acquisire dati, le cifre prestazionali assolute risultano molto difficili da quantificare, pertanto spesso è difficile fondamentalmente fare confronti tra simili RTOSes. Comunque, i dati sotto riportati sono stati ottenuti da, e fanno riferimento rispettivamente ad, un Pentium II 233 MHz e piattaforme 486. Per questi dettagli prestazionali, una prima versione del modulo RTHAL si è dimostrata eseguibile su un timer a 125 KHz (Pentium II 233 MHz) mentre simultaneamente serviva Linux che stava a sua volta lavorando in condizioni di sovraccarico. Durante questa dimostrazione, il jitter medio e massimo del timer periodico erano rispettivamente 0 µs e 13 µs. Queste performances, combinate con test addizionali, possono essere riassunte nel seguente modo: • Maximum periodic task iteration rate: 125KHz ; • Typical sampling task rate: 10KHz (Pentium 100) ; • Jitter at maximum task iteration rate: 0-13µs UP, 0-30µs SMP ; • One-shot interrupt integration rate: 30KHz (Pentium-class CPU), 10KHz (486class CPU) ; • Context switching time: circa 4µs ; 3.3.17 Sviluppi futuri RTAI continua a svilupparsi ed a maturare grazie ai contributi combinati del team di sviluppo DIAPM e a quelli attraverso internet che sono favoriti dalla flessibilità dell’architettura di RTAI, dall’alto set di prestazioni e caratteristiche. Bensì questa estensione real-time di Linux sia oggigiorno molto efficace, stabile e matura, il lavoro è tuttavia lontano dall’essere definito completo. Il futuro riserva molte cose, incluso: 36 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI • Librerie di compatibilità VxWorks; • Librerie di compatibilità pSOS; • Migliorati tools di sviluppo; • Migliorati tools per il debug; • Funzionalità Ethernet Real-Time. 3.4 RTLinux versus RTAI Dopo aver fornito una descrizione dettagliata di due delle possibili alternative hard realtime per Linux, ho ritenuto interessante realizzare un confronto “comparato” tra queste due diverse implementazioni per mettere in risalto, ove possibile, le caratteristiche peculiari di ognuna di esse. 3.4.1 Introduzione Esistono due differenti approcci che permettono di fornire a Linux prestazioni real-time: • Migliorare la prelazione del kernel di Linux; • Aggiungere un nuovo livello software sotto il kernel di Linux che abbia pieno controllo sugli interrupts ed un ruolo “chiave” all’interno del processore. Ci sono due gruppi di lavoro per ogni approccio: “TimeSys” ed il “Linux kernel preemption project”(supportato da Montavista) sviluppano il primo approccio: entrambi i gruppi lavorano in parallelo al fine di produrre un risultato simile. Il secondo approccio invece è supportato da RTLinux ed RTAI. Vediamo ora come le performances real-time vengano realizzati in entrambi, RTLinux ed RTAI. La risposta a questa domanda può essere trovata analizzando attentamente la guida alla programmazione di RTAI, da dove si evince che: “Lo scheduler di Linux real-time considera il kernel del sistema operativo Linux come un idle task (task inattivo). Linux va in esecuzione solo quando tasks real-time da 37 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI eseguire, e quando il kernel real-time è inattivo. Il task di linux non può mai bloccare gli interrupts o evitare di essere prelazionato. Il meccanismo che rende possibile ciò è la simulazione software dell’hardware di controllo dell’interrupt.” Ci sono alcune caratteristiche intrinseche real-time che sono archiviate all’interno dello spazio del kernel da tasks real-time che sono in esecuzione in quell’istante: • Tasks real-time (threads) vengono eseguiti all’interno dello spazio di memoria del kernel, ciò evita che i threads siano non paginati in memoria (swapped-out) ed anche che il numero di TLB mancanti sia ridotto; • I threads vengono eseguiti all’interno del processore in modalità kernel (“supervisor”) ed hanno pieno accesso all’hardware sottostante; • Dal momento che sia l’ RTOS che l’applicazione fanno riferimento insieme ad un “singolo” spazio di esecuzione, è stato implementato il meccanismo della system call col significato di una semplice chiamata a funzione (non utilizzando affatto un interrupt del software che produrrebbe costi senz’altro più elevati). 3.4.2 Licenze e patenti Allo stato attuale in commercio troviamo una diversa situazione per le due piattaforme analizzate. RTLinux viene rilasciato sotto due differenti licenze: 1. Open RTLinux Patent License. Questa licenza permette di usare RTLinux senza tariffe in due particolari situazioni: 1. Per mezzo di software rilasciato sotto GPL; 2. Per mezzo di software che “gira” all’interno di un ambiente di esecuzione RTLinux “aperto” (Open RTinux Execution Environment) – se quel software è rilasciato o meno sotto licenza GPL; 38 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI dove, “Open RTinux Execution Environment ” sta a significare un sistema hardware di computer dove l’hardware di controllo dell’ interrupt dei processori ed i livelli del sistema sono sotto il controllo diretto di un immutato Software RTLinux di tipo “Open” in forma binaria. Alcune modifiche del codice, coperte mediante la Licenza RTLinux Open, sono dovute alla licenza GPL 2 (completamente GPL 2). Cioè il codice non può in alcun modo essere “chiuso” ma, in altri termini, deve essere “aperto” (open) e disponibile sul web per eventuali implementazioni. Inoltre dal momento che non è LGPL non è nemmeno “legale” associarlo ad un codice non-GPL. 2. Non-free License ( in questa analisi il termine “non-free” è preferito a quello “commerciale” ). FSMLabs, ovvero gli inventori di tale piattaforma real-time, obbligano a comprare una licenza commerciale a chiunque voglia imporre restrizioni proprietarie all’uso dei suoi prodotti, cioè voglia distribuire il suo lavoro derivato (basato su RTLinux) a terzi, imponendogli di utilizzare una licenza diversa da quella GPL. La licenza commerciale è simile a quella utilizzata dalla QT Library prodotta dalla TrollTech. L’idea principale di queste licenze, è quella che chiunque può far quello che vuole ma senza guadagnarci economicamente perché, se così non fosse, allora sarebbe costretto a comprare una licenza. Gli FSMLabs hanno brevettato (U.S Patent No. 5,995,745) il processo di cattura degli interrupt e forniscono a Linux un hardware “virtuale” così che RTLinux possa avere il pieno controllo della macchina per fornire una risposta di tipo hard real-time. Questa è una patente software che non è applicabile in Europa ma è valida solo in USA. RTAI invece, utilizza per lo più patenti di tipo LGPL 2. Questo tipo di patenti stanno a significare sostanzialmente che gli utenti possono modificare il codice (come in qualche programma GPL) ma è anche però possibile utilizzare moduli proprietari che possono essere associato od usati assieme al codice RTAI. Il core di RTAI è GPL dal momento che il lavoro proviene dal codice originale RTLinux. La situazione della licenza RTAI non è però chiara. E’ persino possibile (laddove le patenti software sono imposte, comunque non in Europa) che si debba comprare una licenza dagli FSMLabs per poter utilizzare RTAI. 39 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Dal punto di vista accademico, RTLinux ed RTAI sono la stessa cosa: chiunque può utilizzare e modificare il codice come meglio crede. Però mentre il team RTAI cerca forse di consentire uno sviluppo proprietario in maniera gratuita (“for zero prize”), RTLinux non lo fa. La licenza RTAI (LGPL) sembra essere non troppo “legale”, nel senso che RTAI è basato sul codice GPL pertanto non è possibile cambiare la licenza senza il permesso di tutti i possessori dei diritti d’autore (copyright) del codice. In altre parole, lavori derivati dal codice GPL non possono essere rilasciati sotto una licenza differente da essa. 3.4.3 La compatibilità con l’API In RTLinux la libreria API viene implementata come un POSIX 1003.13 “Minimal Real-Time Operatine System”. Il progetto interno è pertanto guidato dalle direttive e dalle esigenze dello standard POSIX. In RTAI invece, la situazione è alquanto diversa: RTAI supporta la sua propria libreria API derivata dall’API della versione RTLinux V1. I nuovi servizi (code per messaggi, mailboxes, etc..) non delineano un’API coerente ed oltretutto sono incompatibili tra loro. Lo stesso servizio viene implementato in molti modi con differenti system calls. RTAI mantiene la compatibilità con l’API della versione RTLinux V1. Esiste un modulo POSIX che fornisce la funzionalità POSIX 1003.1c.(PThreads) e quella 1003.1b.(Pqueues). 3.4.4 Architettura e livello di sviluppo Per quel che concerne le architetture, in RTLinux sono supportate rispettivamente: • L’architettura i386; • L’architettura PPC; • L’architettura ARM; mentre in RTAI è consentito l’uso delle seguenti strutture architetturiali: • L’architettura i386; • L’architettura PPC; 40 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI • L’architettura MIPS; • L’architettura ARM; • L’architettura m64k-nommu; Per quanto riguarda invece l’attuale stato di sviluppo dei due sistemi operativi real-time è importante sottolineare come per RTLinux lo sviluppo temporeggi sulla versione “3.1” (Maggio 2001) ed i kernel di Linux supportati sono rispettivamente il 2.2.19, il 2.4.4 (non ufficialmente 2.4.18 , non supporta SMP), mentre il sistema operativo RTAI , si può affermare che è oggigiorno ancora attivamente sviluppato ed il kernel di Linux supporto è la versione 2.4.18. 3.4.5 Il debug Per attuare il debug RTLinux utilizza: 1. Un debugging a livello sorgente utilizzando GDB(DDD) con supporto SMP. Direttamente dall’interno della macchina bersaglio (senza superare il debugging necessario); 2. Un tracer che tiene traccia del kernel e degli eventi applicativi; 3. Un POSIX trace. RTAI, invece per tale operazione fa uso precisamente di: 1. kgbd, ovvero di un debugging a livello di sorgente di un Host collegato con una linea seriale; 2. Linux Trace Toolkit (LTT). E’ un sistema caratterizzato da “tracing”completo per il kernel di Linux. Esso include sia i componenti del kernel necessari al tracing, che i tools a livello utente necessari alla visualizzazione dei traces. 41 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.4.6 La gestione della memoria La gestione della memoria avviene con differenti strategie nelle due diverse implementazioni real-time analizzate. RTLinux presenta due possibilità di gestione: • Una memoria dinamica (Dynamic memory). Per default, la memoria deve essere riservata prima che parta il thread real-time. Sono permesse inoltre allocazioni della memoria non dinamiche (malloc e funzioni free); • Una memoria condivisa “Shared memory” (RTLinux l’uso del modulo MBUFF (rispettivamente Linux): Mediante mbuff_alloc, mbuff_free) (Non- POSIX). Anche RTAI offre le stesse possibilità solo, però, le implementa in maniera diversa: • Dynamic memory. Supporta l’allocazione della memoria dinamica con primitive rt_malloc ed rt_free. Queste funzioni non hanno però un comportamento hard real-time (Non-POSIX). • Shared memory (RTLinux Linux) mediante: 1. L’uso del modulo MBUFF (rispettivamente mbuff_alloc, mbuff_free) (Non-POSIX); 2. L’uso del modulo SHMEM (rispettivamente rtai_malloc, rtai_free, rtai_kmalloc, rtai_kfree). Shmem è la versione RTAI, sviluppata da Paolo Mantagazza, che “gira” su molti sistemi allo stesso modo, ma è strettamente dipendente da RTAI (Non-POSIX). 42 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI 3.4.7 La comunicazione tra i processi Per permettere e regolare la comunicazione tra i processi, RTLinux consente: • FIFO, ovvero un meccanismo di comunicazione simile a quello dello UNIX PIPE che può essere utilizzato per permettere la comunicazione tra processi realtime ed anche con normali processi utente di Linux. (Non-POSIX); • Mailboxes, ovvero l’implementazione IPC di Jerry Epplin (rt_mq_open, rt_mq_send, etc..) (absoleto). (Non-POSIX). RTAI offre sia gli stessi servizi (implementati ovviamente in modo differente), che altri servizi atti a migliorare l’efficienza stessa del sistema real-time: • FIFO, ovvero un meccanismo di comunicazione simile a quello dello UNIX PIPE, lo stesso di quello supportato da RTLinux. (Non-POSIX). Fornisce inoltre anche un meccanismo per creare direttamente fifos col proprio nome; • Mailboxes. RTAI consente l’uso di mailboxes. I messaggi vengono ordinati in modalità FIFO. Sono permessi messaggi di differente dimensione. Molteplici mittenti e ricevitori possono leggere (read) e scrivere (write) messaggi dalla o nella stessa mailbox. Esistono più funzioni che si preoccupano di spedire o ricevere messaggi, esse non fanno altro che aumentare la flessibilità del sistema: messaggi “interi”o “parziali”e di tipo “blocking”, “non-blocking”, e “timed”; • Message queues. Fornisce 4 differenti strutture di messaggi intertask(e tra loro incompatibili): 1. Message queues compatibili con le queues dello standard POSIX 1003.b. La funzionalità viene fornita direttamente dal modulo di compatibilità POSIX; 2. Piccoli messaggi sincroni (solo 4 bytes). I messaggi possono essere ordinati per priorità (determinata 43 dall’opzione al tempo di Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI compilazione MSG_PRIORD). Ci sono anche primitive timed che si occupano delle operazioni di “sending” e di “receiving”; 3. Estese operazioni “intertask messaging”. Consente di utilizzare messaggi inter task di diverse dimensioni; 4. Remote Procedure Calls (RPCs). Producono lo stesso effetto dei messaggi sincroni solo che ora vengono accoppiati i tasks che attendono una risposta dal ricevente. Gli RPCs operano come coppie complementari di messaggi “send” e “receive”. (Non-POSIX). • Net_rpc. RTAI ha esteso la sua API al fine di permettere “chiamate a procedure remote” RPC (di altri hosts). Sono state aggiunte nuove funzioni API con la seguente sintassi: basta sostituire le prime due lettere del nome della funzione (per esempio: data la funzione rt_mbx_send(), è stata aggiunta la nuova funzione RT_mbx_send() ); e la nuova funzione avrà due nuovi parametri, ovvero il “node” ed il “port”. E’ importante sottolineare come questa caratteristica non sia conforme ad alcuno standard di comunicazione. Per attuare quindi la comunicazione fra processi, non è desiderabile che vi siano caratteristiche troppo incompatibili tra loro, ridondanti e non-standard. Un sistema operativo real-time (RTOS) dovrebbe in linea di massima fornire una semplice API. 3.4.8 La sincronizzazione Per attuare la sincronizzazione, RTLinux permette l’uso di: • Variabili Mutue. Variabili mutue del POSIX- thread. Forniscono un protocollo “PRIORITY_PROTECT” per superare il problema dell’inversione di priorità; • Variabili condizionali. Varibili condizionali POSIX; • Semafori. Semafori POSIX. 44 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI Anche RTAI consente le stesse primitive di sincronizzazione, però con ulteriori implementazioni: • Variabili Mutue. Variabili mutue del POSIX- thread. Forniscono un protocollo “PRIORITY_INHERIT” per contrastare il problema dell’inversione di priorità; • Variabili condizionali. Varibili condizionali POSIX; • Semafori. 1. Semafori POSIX; 2. Semafori RTAI (rtf_sem_init, rtf_sem_wait, ...) Il meccanismo di fondo utilizzato per implementare questi semafori altro non è che la proprietà di “blocking” del canale FIFO. 3.4.9 Lo spazio utente real-time Lo spazio utente real-time viene implementato in maniera alquanto diversa da RTLinux e da RTAI. La prima piattaforma utilizza sostanzialmente: • Segnali che attuano lo “User-space real-time”. Interrupts a livello hardware e segnali temporali possono essere gestiti da particolari “gestori” di segnali a livello utente. Non è però possibile effettuare alcuna system call di Linux né alcun servizio RTLinux direttamente da questi gestori; • Ulteriori e nuove proprietà nelle distribuzioni commerciali. Per quel che concerne invece la piattaforma RTAI, l’implementazione dello “user-space real-time” è stata ben sviluppata e testata. E’ chiamata LXRT e presenta sicuramente più API rispetto a quante ve ne siano all’interno del kernel-space real-time, fatta eccezione per le API dei threads POSIX. Esistono attualmente almeno tre differenti implementazioni: 45 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI • Servizi LXRT (Soft - hard real-time all’interno dello user-space). LXRT è un modulo che permette di utilizzare servizi RTAI a livello utente (si veda la tabella 1). Viene implementato utilizzando il processo RTAI (essendo eseguito all’interno del kernel-space) per ogni processo LXRT al fine di ottimizzare la chiamata alla funzione attuale. Ogni volta che un processo LXRT richiama una funzione API di RTAI, i parametri vengono copiati nel pari processo RTAI che è l’unico realmente al lavoro. E’ possibile inoltre utilizzare le system calls di Linux direttamente dal processo LXRT, come d’altronde i servizi di RTAI. I tasks dello user-space LXRT possono infine interagire con i tasks del kernelspace di RTAI semplicemente mediante l’uso della stessa API (condividono memoria, scambiano messaggi, usano semafori, etc…); Soft-hard real time in user space API rt_task_init rt_sem_init rt_mbx_init rt_get_adr rt_register rt_get_name rt_drg_on_adr rt_drg_on_name rt_allow_nonroot_hrt Tabella 1 • LXRT esteso (Hard - hard real-time all’interno dello user-space). Questa altro non rappresenta che un’estensione al modulo originale LXRT. Chiamando la funzione rt_make hard_real_time () (si veda la tabella 2), un processo LXRT riceve persino una priorità più alta. Il processo viene schedulato dal kernel di Linux, ma da uno specifico “bottom-half”(un bottom-half è un kernel interno di Linux per l’utilità degli utenti che serve ad eseguire i servizi di interrupts). Come scritto nella guida alla programmazione RTAI 1.0 (si vedano a tal proposito le referenze), “La chiamata alla funzione rt_make hard_real_time () permette di prendere un normale processo al di fuori della running queue di Linux semplicemente richiamando lo schedule() dopo aver accodato il task ad un gestore di livello più basso. Non appena il gestore di più basso livello consente l’esecuzione, il task viene schedulato come un modulo hard real-time senza che Linux si accorga mai di esso, avendolo ancora nella sua lista dei processi da eseguire ”. Questo tipo di processi non dovrebbe richiamare alcuna 46 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI system calls di Linux, la quale potrebbe condurre ad un task-switch che potrebbe causare una deadlock. Extended hard-hard user space API rt_make hard_real_time rt_make_soft_real_time Tabella 2 • Mini RTAI LXRT. Questo modulo fornisce un modo di eseguire funzioni in maniera simile a come vengono eseguiti i tasklets del Kernel 2.4 di Linux (si veda la tabella 3). Questi tasklets sono di due tipi: “normali” e “timed” (timer). Essi possono essere utilizzati per implementare Controllori Logici Programmabili (PLC), ed altri semplici sotto-sistemi real-time. System calls di tipo “blocking”(Linux o RTAI) non dovrebbero essere richiamate dai tasklets. Attualmente, (RTAI 24.1.9) i processi Mini_RTAI_LXRT possono non essere comunemente utilizzati. Mini RTAI functions rt_task_init rt_insert_tasklet rt_tasklet_exec rt_task_delete rt_remove_tasklet rt_timer_init rt_set_timer_priority rt_set_timer_handler rt_remove_timer rt_set_timer_period rt_set_timer_data Tabella 3 Ci sono due principali ragioni per eseguire le applicazioni real-time direttamente all’interno dello user-space: 1. Un task crash, essenzialmente dovuto ad un buco nella programmazione, non va ad affliggere la stabilità del sistema. Quando il crashing del task termina, il 47 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI sistema resta comunque al sicuro: il che produce uno sviluppo più rapido del sistema stesso. 2. E’ più semplice rispetto all’inserimento diretto dei moduli nel kernel. L’applicazione real-time è “codificata” ed “inizializzata” esattamente come un normale processo UNIX. Mediante l’uso della libreria API di POSIX, è possibile utilizzare la stessa API sia per lo user-space che per il kernel-space. Pertanto risulta inefficiente effettuare il “porting” (portare le API di RTAI o di RTLinux) ai processi dello user-space. Infatti, utilizzando i PThreads di Xavier Leroy è possibile implementare applicazioni soft real-time direttamente all’interno dello user-space. Anche l’uso del nuovo kernel “prelazionabile” riduce la latenza del sistema, in tal modo è possibile avere caratteristiche soft real-time nei normali processi utente di Linux. Con l’uso dei processi dello user-space, tutti i vantaggi che aveva l’esecuzione all’interno del kernel space vengono inevitabilmente persi: ci sono più TLB mancate e si crea un pesante meccanismo di system calls. In una recente discussione nella mailing-list del kernel di Linux, Linus Torvalds ha espresso la propria opinione sullo user-space real-time, ribadendo: “…Con RTLinux, l’applicazione può essere scissa in due parti: la parte “hard real-time”(che finisce per stare nel kernel space) ed il “resto”. Questa scissione rappresenta, secondo me, l’unico modo sensato di gestire l’hard real-time. Non si ha alcuna confusione riguardo il problema dell’ inversione della priorità, e ne alcun crash. Ridurre i confini tra cosa “deve accadere ora” e “ciò si può fare con un abituale soft real-time ”…” 3.4.10 Tabella riassuntiva La seguente tabella riassume in maniera alquanto semplice le principali differenze risultanti dall’analisi svolta dei due RTOS. Ovviamente non vengono incluse le caratteristiche che caratterizzano entrambi i sistemi. 48 Capitolo 3 Le più diffuse alternative hard real-time oggi sul mercato:RTLinux ed RTAI RTLinux RTAI Company FSM Labs DENX Software Engineering, Pengutronix and Sysgo Realtime Solutions Arch i386, PPC, ARM i386, MIPS, PPC, ARM, m68k-nommu License GPL Comercial LGPL - GPL API POSIX custom Memory shared dynamic and shared Debug GDB, Event tracer Cross GDB, LTT IPC FIFO's FIFO's, Named FIFO's, Mailboxes, messages, PQueues, net_rpc User space Real Time Signal handlers LXRT soft, LXRT hard, Mini LXRT Misc RT-Lab Octave, proc, Watchdog, Scripting, Xenomai Tabella 4 49 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Capitolo 4 Un’estensione firm real-time di Linux : il KURT 4.1 Premessa Il KURT (acronimo di Kansas University Real Time Linux) altro non è che una modifica real-time al sistema operativo Linux, che consente lo scheduling di eventi realtime alla risoluzione di 10µs. Piuttosto che contare su uno scheduling basato su priorità o su “rigidi” schedules periodici, schedules del sistema operativo KURT sono esplicitamente specificati dal programmatore dell’applicazione. KURT può tuttavia funzionare in due modi: “focussed mode”, dove solo ad i processi real-time è permessa l’esecuzione; ed il “mixed mode”, dove l’esecuzione dei processi real-time ha ancora la precedenza, ma è consentito a tutti i processi non real-time di essere eseguiti purchè all’interno dei “buchi” dello schedule real-time. Il KURT “gira” su una piattaforma compatibile x86 con un contatore di tipo “time-stamp” (ossia i processori Pentium o i loro equivalenti). 4.2 Un’introduzione al KURT Generalmente i sistemi real-time vengono classificati, come d’altronde ribadito nel capitolo 3, in due categorie di sistemi: i sistemi “soft real-time” e quelli “hard realtime”. E’ però evidente che una simile distinzione (puramente binaria) non può essere chiaramente accettabile per tutte le applicazioni. Molte applicazioni presentano infatti esigenze che abbracciano entrambe le due distinzioni. Pertanto, al fine di soddisfare un range più vasto di richieste, l’università del Kansas ha sviluppato una versione “firm”real-time di Linux ed ha chiamato questo sistema “KURT” Linux. KURT Linux tiene conto dello scheduling esplicito degli eventi real-time piuttosto che solo dei processi. Questo sistema operativo fornisce una più generica struttura sulla 50 Capitolo 4 Un’estensione firm real-time di Linux : il KURT quale viene mappato il normale scheduling dei processi real-time. Dal momento che lo scheduling dell’evento è gestito direttamente dal sistema, l’aggiunta di nuovi eventi come schede di acquisizione dati per il campionamento periodico (video, apparecchiature da laboratorio, etc…) risulta altamente semplificata. KURT introduce due possibili modi di funzionamento: la modalità “normale” e quella “real-time”. Nella modalità “normale”, il sistema agisce come un generico sistema Linux. Non appena il kernel sta lavorando in modalità real-time, esso esegue solo i processi real-time. Quindi nella modalità “real-time”, il sistema può essere usato non più come una piattaforma generica, dal momento che tutte le sue risorse sono dedicate ad eseguire le sue “responsabilità” real-time il più accuratamente possibile. Una semplice system call permette che il kernel possa passare dalla modalità real-time a quella normale. Durante la fase di setup, lo schedule degli eventi che devono essere eseguiti in modalità real-time è specificato, ed i vari processi che stanno per essere eseguiti in tale modalità vengono contrassegnati. Il kernel passa poi (switch) in modalità real-time. Non appena tutti i tasks real-time terminano la loro esecuzione, il kernel può tornare ad operare (switch back) in modalità normale. Attualmente, questo sistema è disponibile solo per l’architettura i386. Effettuare il “porting” di KURT ad altre architetture, richiede tuttavia solo minime aggiunte. 4.3 Passi salienti dell’RTOS KURT Il sistema operativo KURT generalmente fa uso della seguente sintassi per attuare la propria politica real-time: • Eventi real-time : Gli eventi real-time possono essere definiti come particolari eventi che necessitano di essere schedulati in modalità “real-time”. Per esempio, se si volesse scrivere un generatore di traffico che generi appunto traffico secondo uno schedule predefinito, questo non sarebbe altro che un vero e proprio evento real-time, inoltre un sistema siffatto potrebbe essere anche usato per testare le prestazioni di apparecchiature di rete come switches, etc.. . Per realizzare ciò in un normale sistema real-time, quest’ ultimo dovrebbe comportare la scrittura di un processo utente il quale dovrebbe generare il traffico real-time e lo dovrebbe scrivere ad una socket. Un tale sistema è di per sé inefficiente poiché causa uno switching eccessivo tra il kernel space e lo user 51 Capitolo 4 Un’estensione firm real-time di Linux : il KURT space. Un altro problema sempre in un tale sistema è quello che, una volta che il processo utente ha scritto i dati alla socket, decide solo il kernel quando mandarli fuori dalla scheda di interfacciamento alla rete (NIC). Quindi lo scopo totale del generatore di traffico, in accordo con un modello specifico, verrebbe soppiantato. Il KURT risolve questo problema introducendo il noto concetto di modulo real-time; • Struttura real-time(real time framework) : Il KURT si compone di una struttura real-time (framework) che si preoccupa di realizzare lo scheduling di eventi real-time. Quando un evento real-time sta per essere eseguito, la struttura real-time chiama il gestore degli eventi (event handler) dell’ RTmod associato. Dividendo le funzionalità dello scheduling e l’esecuzione attuale in due entità separate, gli sviluppatori del KURT hanno semplificato il processo di aggiungere maggiori funzionalità al loro sistema real-time. Per esempio aggiungere la capacità di generare traffico di rete, in accordo con un specifico schedule, diviene così semplice come scrivere un RTMod che dovrebbe permettere alla scheda di rete di emettere un pacchetto ogni qual volta che viene invocato. La responsabilità della struttura real-time altro non è che quella di effettuare lo scheduling delle chiamate a questo modulo RTMod. Questa struttura fornisce system calls che realizzano lo switch del kernel dentro e fuori la modalità real-time, schedulano gli eventi real-time ed elencano tutti i moduli real-time registrati; • I Moduli real-time : I Moduli real time (RTMods) sono moduli del kernel, che possono essere caricati a “runtime” ottimizzando così certe azioni quando vengono invocati. Gli sviluppatori della piattaforma KURT hanno scritto un RTMod che cambia il contesto al processo utente specificato non appena è invocato. Essi hanno inoltre scritto un RTMod che inverte (flip) i bits di una porta parallela. Un modulo real-time cosiffatto, deve necessariamente appartenere ad una struttura real-time. Un modulo real-time che è sempre presente è il modulo “process”. Questo modulo, quando viene invocato, schedala il risveglio(wake up) di un processo; 52 Capitolo 4 • Un’estensione firm real-time di Linux : il KURT rt-id : Altro non è che il numero identificativo associato ad ogni processo del KURT. Ogni processo del KURT può infatti richiedere (o essere dato da) un rtid non appena esso viene registrato nel modulo di processo settando set_rtparams. Un processo KURT può modificare il suo rt_id utilizzandola medesima system call; • Registrazione degli RTMods : Un RTMod registra se stesso all’interno del framework real-time provvedendo ad un nome, a dei puntatori a funzione per i gestori degli eventi, all’inizializzazione, ed alla sua eventuale ripulitura(clean up). Quando un modulo real-time viene registrato, gli viene assegnato un numero identificativo che viene utilizzato per schedulare gli eventi di questo particolare modulo; • Lo schedule real-time : Uno schedule real-time è un file che specifica come ed in che momento l’RTMod necessiti di essere invocato. Questo schedule viene poi passato al framework real-time che si prende cura dello scheduling di ogni evento invocando, nel momento giusto, l’appropriato gestore degli eventi. Gli sviluppatori del KURT hanno realizzato un semplice programma che genera questo schedule; • Scheduling Modes : Il framework real-time può schedulare eventi secondo due modalità: 1. FROM_MEM : Nella seguente modalità , il file di schedule viene completamente letto nella memoria del kernel e solo poi lo scheduling di ogni evento ha luogo. E’ possibile ripetere questo schedule per un numero di volte in maniera ciclica. Lo svantaggio di questa modalità è che richiede abbastanza memoria per occupare il file di schedule completo. Si pensi infatti che ogni evento occupa circa 24 bytes di memoria. 2. FROM_DISK : In questa modalità, il file di schedule viene letto nella memoria del kernel una pagina per volta. Arbitrariamente, lunghi schedules possono essere presentati al 53 Capitolo 4 Un’estensione firm real-time di Linux : il KURT framework real-time per lo scheduling. Lo svantaggio di questa modalità è che ci potrebbero essere alcune distorsioni nello scheduling degli eventi a causa dell’operazione di lettura intermittente da disco. • UTIME : Il KURT utilizza un sistema “utime” per schedulare gli eventi con una risoluzione in termini di microsecondi (µs). Gli eventi possono anche esser schedulati con una risoluzione di 10 ms se UTIME non è installato. 4.4 La struttura di un “executive process” Un “executive process ” controlla lo scheduling di tutti i processi KURT e di tutti gli RTMods. Le principali azioni che intraprende un executive process sono mostrate sotto: int main() { setta lo scheduler del processo corrente alllo SCHED_KURT; attende ce tutti I processi KURT siano registarti; effettua lo switch in modalità real-time; schedala gli eventi real-time; effettua lo switch in modalità normal; } Nella versione corrente del KURT (v1.23) gli sviluppatori di tale siatema non necessitano di un “execute process” per schedulare periodicamente i processi. Ognuno dei processi periodici schedula se stesso. L’attività di questo scheduling inizia quando viene rilasciata la prima chiamata ad rt_suspend. 4.5 La struttura di un processo KURT La maggior parte dei processi KURT hanno la seguente struttura: 54 Capitolo 4 Un’estensione firm real-time di Linux : il KURT int main() { setta lo scheduler del processo corrente alllo SCHED_KURT; while(1) { si sospende finchè viene risvegliato da un executive process; esegue il suo compito; } } 4.6 Innovazioni dell’RTOS KURT alle system calls 4.6.1 Le system calls nel framework real-time Le seguenti system calls sono presenti all’interno del framework del core real-time: • switch_to_rt : Permette di realizzare lo “switch” del kernel in modalità realtime. Una volta che il kernel viene portato in modalità real-.time (con rt_mode = SCHED_KURT_PROCS), solo i processi che sono contrassegnati come processi SCHED_KURT possono essere eseguiti. Se nella chiamata a switch_to_rt si verifica che rt_mode = SCHED_ALL_PROCS, allora a tutti i processi è permessa l’esecuzione, ed i processi KURT possono essere esplicitamente schedulati. Il prototipo di questa system call è: int switch_to_rt(int timer_mode, unsigned long period, int rt_mode, char *cmdline, int length); dove “cmdline” è una stringa di caratteri che viene passata alla funzione iniziale di tutte quelle registrate RTMod. Ad esempio per passare qualcosa al modulo del processo, “cmdline” dovrebbe essere “process=xxxxx”. Il kernel passa allora gli appropriati parametri ad i vari moduli, identificati dal nome dei moduli. “lenght” infine, è la lunghezza del cmdline. 55 Capitolo 4 • Un’estensione firm real-time di Linux : il KURT rtmod_cmd : Questa system call permette ad un modulo real-time di fornire una nuova interfaccia al programma utente che la usa. Usando questa system call il programma utente può chiedere all’RTMod di ottimizzare una certa azione. Il corretto RTMod viene così localizzato ed il comando ed il buffer gli vengono passati. Il prototipo è: int rtmod_cmd(int rtmod_id, int command, void *buf, unsigned long length); • switch_to_normal : Permette di realizzare uno “switch” all’indietro del kernel, riportandolo in modalità normale. Ciò consente l’uso del PC come una normale workstation. Il parametro “force” può essere settato per forzare il kernel a passare in modalità “normal”, mediante la cancellazione di tutti gli eventi che sono stati già schedulati. Qualora il parametro “force” non venga settato, la chiamata si blocca finché tutti gli eventi che sono stati gia schedulati non hanno completato la propria esecuzione. Il prototipo è: int switch_to_normal(int force); • rt_schedule_events : Questa system call schedula gli eventi esattamente come avviene per il file di schedule. Il prototipo di questa system call è: int rt_schedule_events(struct timeval *start_time, int sched_mode, int num_times, char *filename); dove: “start_time” è il tempo in cui lo scheduling dovrebbe partire; “num_times” è utilizzato solo nel caso in cui la modalità di scheduling è FROM_MEM; • get_rtmod_num : Questa non è una system call ma una “library call” inclusa in librt.a. Questa chiamata consente ad un utente di raggiungere l’RTMod Id di un modulo semplicemente passando a questa funzione il nome di RTMod. Il prototipo di questa chiamata è il seguente: 56 Capitolo 4 Un’estensione firm real-time di Linux : il KURT int get_rtmod_num(char *name); 4.6.2 Le system calls nel modulo di processo Il “modulo di processo”, non appena viene invocato, si preoccupa di effettuare lo switching di contesto di un processo specificato. Esso modifica alcune system calls esistenti, ed in aggiunta, fornisce altre system calls che sono di seguito menzionate: • set_rtparams : Questa system call è stata aggiunta al kernel di Linux al fine di contrassegnare un particolare processo come un processo SCED_KURT. Solo a questi processi, la cui politica di scheduling è SHED_KURT, è concessa l’esecuzione in modalità real-time. Ciascun processo può richiedere un rt_id che viene utilizzato quando si sta schedulando un processo real-time. Il prototipo è: int set_rtparams(int pid, int policy, struct rtparams *); “pid” è il PID(process identification) del processo i cui “rtparams” si stanno modificando. Se questo parametro viene settato a zero, allora la chiamata viene applicata al processo in esecuzione corrente. “policy”: Questo termine specifica la “politica” di scheduling a cui il processo dato dovrebbe essere settato. Così per contrassegnare un processo come processo real-time si potrebbe settare la “policy” ad essere SCHED_KURT. Anche per eliminare da un processo il contrassegno SCHED_KURT, si ha bisogno di settare quest’ultimo a SCHED_OTHER, oppure a SCHED_FIFO, o ancora a SCHED_RR (è importante sottolineare che si può usare la system call sched_setscheduler per eliminare la marcatura SCHED_KURT da un processo). “struct rtparams” : Questa struttura specifica le caratteristiche del processo SCHED_KURT. Esso viene definito come segue: struct rtparams { 57 Capitolo 4 Un’estensione firm real-time di Linux : il KURT int rt_id; int priority; unsigned long proc_req; unsigned long period; } “priority”: KURT utilizza un meccanismo di scheduling round-robin per schedulare processi che non son stati esplicitamente schedulati. Questo membro di rtparams determina la priorità del processo KURT. “proc_req”: Ogni volta che viene invocata esprime la richiesta di processamento del corrente processo. Se la modalità di scheduling è quella “periodica”, allora il processo successivo sarà schedulato esattamente “proc_req” microsecondi dopo questo processo. Il kernel si preoccupa quindi di includere i “costi” di scheduling mentre sta schedulando questi processi. “period”: E’ il periodo del processo considerato. Attualmente tutti i processi KURT dovrebbero avere lo stesso periodo. Questo può essere settato a zero, per processi aperiodici che saranno schedulati mediante l’uso della system call rt_schedule_events. Non appena un processo SCHED_KURT viene generato(fork) o clonato (clone), il processo figlio eredita lo status “SCHED_KURT”. Il processo RTMod si preoccupa di assegnare un rt_id al processo figlio. Questo rt_id può essere modificato mediante una chiamata alla system call set_rtparams. L’informazione sulla politica di scheduling, oltre all’ rt_id ed alle richieste di processamento di un processo, può essere ottenuta utilizzando la system call get_rtparams (è importante notare come il processo generato eredita la priorità del processo padre ed è contrassegnato da un richiesta di processamento pari a “0”); • get_num_rtprocs : Restituisce il numero di processi di tipo SCHED_KURT. Il prototipo è: 58 Capitolo 4 Un’estensione firm real-time di Linux : il KURT int get_num_rtprocs(void); • rt_suspend : Sospende un processo SCHED_KURT finchè esso viene risvegliato dal modulo di processo. Si noti la struttura di un processo KURT sopra descritto (par 4.4) per maggiori dettagli sull’uso di questa system call. Il prototipo è il seguente: int rt_suspend(int susp_mode); “susp_mode”: Può essere o di tipo START_SCHED oppure STOP_SCHED. Se il processo è periodico (cioè rt_params.period != 0) allora START_SCHED inizia lo scheduling del processo in accordo col suo periodo. STOP_SCHED arresta invece lo scheduling di un processo periodico. Oltre a questi due “flags” c’è anche una terza possibilità, ovvero SUSPEND_IF_NRT che causa la sospensione dei processi finché il kernel non commuta in modalità real-time dopo di che esso può iniziare lo scheduling. I processi schedulati esplicitamente (cioè quei processi che vengono schedulati mediante l’uso di un file di schedule) non necessitano dell’uso di flags come START_SCHED e STOP_SCHED; • get_rt_stats : Restituisce una struttura rtstats per il processo corrente. La struttura rt_info ha la forma (si veda il par 4.4): struct rtstats { int rt_id; int rt_abort; int suspended; unsigned long rt_num_woken_up; unsigned long rt_num_suspended; unsigned long rt_num_missed; } “rt_abort” viene settato quando un processo supera il tempo che gli è stato allocato, ed un altro processo viene schedulato. Questo significa che il processo necessita di abortire ciò che sta facendo e allo stesso tempo “performare” un rtsuspend il prima possibile. 59 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Il campo “suspended” viene settato non appena un processo effettua una chiamata alla system call rt_suspend. “rt_num_woken_up” è il numero di volte che il processo corrente è stato risvegliato. “rt_num_suspended” è il numero di volte che il processo corrente ha attuato un rt_suspend. “rt_num_missed” è il numero di volte che il processo corrente manca il suo scheduling perché non ha finito la sua iterazione precedente. 4.7 /Proc filesystem Gli sviluppatori del KURT hanno aggiunto un nuovo ingresso all’interno del /proc filesystem chiamato appunto “rt”. Questa nuova directory presenta ingressi per le informazioni statistiche del sistema real-time (come per esempio il numero di eventi che vengono gestiti, il numero di eventi ritardati, etc…) direttamente nella sottodirectory per le informazioni statistiche. I vari RTMods registrati, possono essere trovati nell’ingresso rt_mods. I vari processi real-time che sono stati registrati e le loro relative informazioni statistiche quindi, possono essere trovate all’interno dei processi stessi. 4.8 Files modificati Un’intera nuova directory, chiamata rt, è stata introdotta dagli sviluppatori di tale software all’interno del source del kernel. Oltre i files propri di questa directory, sono stati aggiunti o modificati i seguenti files: kernel/sched.c kernel/sysctl.c kernel/fork.c kernel/exit.c arch/i386/kernel/entry.S 60 Capitolo 4 Un’estensione firm real-time di Linux : il KURT arch/i386/kernel/setup.c mm/vmscan.c init/main.c include/asm-i386/unistd.h include/linux/rt.h include/linux/sched.h drivers/char/sysrq.c 4.9 Performances dell’RTOS KURT Per valutare le performances del sistema operativo real-time KURT, non potendo confrontare direttamente le sue prestazioni di natura ovviamente “firm real-time” con quelle di natura “hard real-time” degli RTOS analizzati nel capitolo 3 (un tale confronto sarebbe alquanto insignificante vista la diversa politica di scheduling delle due diverse piattaforme), ho ritenuto più idoneo descrivere i tests effettuati dai suoi sviluppatori, sostanzialmente mirati ad: • esaminare il “dispatch time” per i moduli del kernel e per i processi real-time; • realizzare un più “equo” confronto con uno scheduler FIFO soft real-time; • valutare infine l’effetto di “blocking” degli interrupt. 4.9.1 Il dispatch time dei moduli del kernel e dei processi real-time Per testare il tempo richiesto ad invocare un modulo del kernel ed un processo real-time, gli sviluppatori hanno scritto un semplice processo real-time KURT che veniva eseguito automaticamente ogni 10ms (nella modalità periodica). Lo pseudo-codice di questa applicazione è mostrato in figura 17. 61 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Fig. 17 – Pseudo-codice di un programma che testa il dispatch time di processi e moduli real-time Ogni volta che cicla, il programma restituisce il tempo corrente e lo immagazzina in memoria. Dopo che il programma ha terminato la sua esecuzione, i tempi vengono stampati al fine di permettere un immediato confronto. Le informazioni temporali, inoltre, sono state anche conservate per valutare la differenza tra quando un evento occorre nel tempo e quando l’RTMod inizia realmente la sua esecuzione. La figura 18 mostra appunto tale differenza, presentando simultaneamente anche il tempo in cui il processo utente ha iniziato la propria esecuzione. Fig. 18 – Distribuzione delle differenze tra il tempo in cui l’evento è schedulato e quello reale 62 Capitolo 4 Un’estensione firm real-time di Linux : il KURT 4.9.2 KURT versus lo scheduler FIFO soft real-time Al fine di confrontare il KURT con uno scheduler FIFO soft real-time, un’altra applicazione è stata scritta dagli sviluppatori di questo software che utilizzasse uno scheduler FIFO. Questo programma, mostrato in figura 19, è sostanzialmente lo stesso di quello di figura 17 (in entrambi i casi la distanza temporale tra due successive iterazioni del ciclo è di 10ms) solo che ora in aggiunta utilizza la system call select per sospendere se stesso. Fig. 19 - Pseudo-codice di un programma che testa l’efficacia dello scheduler SCHED_FIFO Tests sono stati svolti con i programmi di figura 17 e 19 utilizzando rispettivamente 1, 10, 20 e 30 processi concorrenti. Sotto la piattaforma KURT, sono state testate sia la modalità di scheduling “mixed” che quella “focused”. Eccetto per i vari processi da testare, il sistema era in stato idle. La figura 20 mostra gli istogrammi ottenuti nel caso di SCHED_FIFO. Questi istogrammi rappresentano la percentuale di iterazioni in funzione della differenza temporale tra due iterazioni consecutive. La figura 21 rappresenta gli istogrammi ottenuti nel caso di SCHED_KURT con modalità real-time settata ad SCHED_KURT_PROCS (focus mode) mentre la figura 22 mostra gli istogrammi ottenuti in modalità SCHED_ALL_PROCS (mixed mode). 63 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Fig. 20 – Efficienza di scheduling dello SCHED_FIFO 64 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Fig. 21 – Efficienza di scheduling dello SCHED_KURT(modalità focus o SCHED_KURT_PROCS) 65 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Fig. 22 – Efficienza di scheduling dello SCHED_KURT(modalità mixed o SCHED_ALL_PROCS) Da un’analisi attenta di queste figure, si possono dedurre le seguenti osservazioni: • Nel caso dello SCHED_FIFO, le performances del sistema, in termini di varianza di scheduling, peggiorano all’aumentare del numero dei processi. Ciò può esser attribuito al fatto che, a causa degli interrupts dell’hardware esterno, ci sarebbe un considerevole numero di contex switch prelazionabili all’interno di questi processi che inevitabilmente affliggerebbe le loro prestazioni; • Nel caso dello SCHED_KURT, le performances sostanzialmente restano invariate quando viene aumentato il numero dei processi. Dal momento che questi processi KURT vengono schedulati esplicitamente, c’è un minimo contex switch tra queste applicazioni; • Quando i processi utilizzano la politica di scheduling SCHED_KURT, non c’è quasi differenza tra la modalità 66 SCHED_KURT_PROCS e quella Capitolo 4 Un’estensione firm real-time di Linux : il KURT SCHED_ALL_PROCS. Ciò si verifica perché il sistema è essenzialmente idle eccetto per i processi da testare; • Nel caso dello SCHED_KURT, non c’è un vero e proprio meccanismo di controllo dell’ ingresso che previene l’overloading della CPU. Dal momento che ogni processo setta le sue richieste di processamento a 300µs (questo corrisponde all’attuale tempo di CPU richiesto dal processo per completare un’iterazione del suo ciclo), non sono permessi più di 30 processi all’interno del sistema. Invece, nel caso dello SCHED_FIFO, qualsiasi numero dei processi dovrebbe essere permesso all’interno del sistema. Questo dovrebbe portare ad un ulteriore degradazione delle performances; Da queste osservazioni si può concludere che lo scheduling esplicito, con o senza focalizzazione del set dei processi in esecuzione, rappresenta un’alternativa fattibile per realizzare lo scheduling firm real-time dei processi. La figura 23 riassume il risultato mostrato nelle figure 20, 21, e 22. 67 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Fig. 23 – Effetto del numero di processi sullo scheduling Questa figura illustra la percentuale di iterazioni con durata minore di o uguale ad un dato valore sull’asse orizzontale. La figura 23 (a) mostra chiaramente che la varianza delle performances dello scheuler FIFO incrementa significativamente all’aumentare del numero dei processi, mentre quella relativa allo scheduler KURT no. A prescindere dal numero dei processi, il KURT schedula ogni applicazione al tempo appropriato. La tabella 5 raffigura un confronto tabulare dei tre schedulers. In queste tabelle, viene mostrata la probabilità che un evento si verifichi entro una durata di tempo specificata dal tempo aspettato. 68 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Tabella 5 – Intervalli di confidenza per lo scheduling di processi che utilizza differenti schedulers Come si può vedere osservando la tabella 5 (a), lo SCHED_FIFO potrebbe probabilmente essere adatto per l’esecuzione di 1 processo firm real-time. Per esempio, il 62% degli eventi cade all’interno dei 10µs (cioè lo 0.1%) del tempo atteso, mentre il 100% degli eventi cade all’interno dei 500 µs (cioè lo 5 %)del tempo atteso. Ma, non appena il numero dei processi FIFO viene incrementato, le performances crollano drasticamente. Per esempio, con 30 processi, solo 1.21% degli eventi cade dentro lo 0.1% del tempo atteso, e solo il 46.61% dentro il 5% del tempo atteso. Le performances sono “attese” per ridurre ulteriormente quanti più processi sono aggiunti al sistema. Contrariamente, nel caso dello SCHED_KURT in modalità SCHED_ALL_PROCS (mixed mode), come mostrato in Tabella 5 (b), per 1 processo il 99.8% degli eventi cade dentro lo 0.1% del tempo atteso, mentre il 100% dentro il 5% del tempo atteso. Per 30 processi, il 97.3% degli eventi cade all’interno dello 0.1% del tempo atteso, ed il 99.99% cade dentro il 5% del tempo atteso. 69 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Le prestazioni dello scheduling esplicito nella modalità SCHED_KURT_PROCS (focused mode), che come si ricorda permette l’esecuzione solo di processi real-time, vengono mostrate in Tabella 5 (c). C’è un leggero miglioramento delle performances dello scheduler esplicito che ha effettuato lo switching del kernel in modalità SCHED_KURT_PROCS quando viene confrontato con la modalità SCHED_ALL_PROCS. Ma questo miglioramento nelle prestazioni non è sostanziale, perché il sistema è essenzialmente “idle” se si escludono i processi schedulati esplicitamente. Se un sistema è caricato, le performances dello scheduler esplicito nella modalità SCHED_ALL_PROCS potrebbero essere distorte nel momento in cui gli interrupts vengono disabilitati da altre parti del sistema operativo. La figura 24 mostra l’effetto dell’attività di backgraund del disco sulle performances degli schedulers FIFO e KURT. Questi esperimenti sono stati condotti con l’attività di backgraund del disco perché il sottosistema “disco” di Linux disabilita gli interruptus per la massima durata del tempo. Fig. 24 – Effetto del numero dei processi sullo scheduling in presenza di attività di background del disco Come si può osservare da queste figure e dalla Tabella 6, l’attività di backgraund del disco distorce lo schedule per durate minori di 500 µs. Ciò si verifica perché il sottosistema disco di Linux disabilita gli interrupts per durate maggiori di 250 µs, e dipende anche dal numero di “back-to-back blocking” degli interrupts: le performances dello scheduler potrebbero essere distorte in quel momento. Si può notare che persino in 70 Capitolo 4 Un’estensione firm real-time di Linux : il KURT presenza di “background disk activity”, lo SCHED_KURT funziona ancora molto meglio dello SCED_FIFO. Tabella 6 – Intervalli di confidenza per scheduling di processi con Background Disk Activity Un’ulteriore considerazione che può essere fatta analizzando attentamente la Tabella 6 (b) è che non appena il numero di processi viene incrementato, le performances dello SCHED_KURT migliorano sostanzialmente. Ciò si verifica probabilmente perché, non appena il numero dei processi aumenta, il processo che genera il background disk activity non viene schedulato così spesso e quindi la durata di tempo nella quale gli interrupts vengono disabilitati viene sostanzialmente ridotta (per 30 processi, come si nota, le performances peggioriorano rispetto al caso dei 20 processi; ciò potrebbe esser dovuto al fatto che per 30 processi il sistema è quasi completamente caricato, ed anche se gli interrupts sono bloccati per un piccolo periodo di tempo, l’effetto di questa distorsione produce a sua volta un effetto a cascata sullo scheduling di tutti i processi KURT ). Il paragrafo seguente (par 4.8.3) presenta alcuni dati che permettono agli sviluppatori dell’applicazione di valutare l’effetto, in termini di distorsioni dello scheduling, risultante dall’uso di alcuni sottosistemi Linux nelle loro applicazioni realtime. 71 Capitolo 4 Un’estensione firm real-time di Linux : il KURT 4.9.3 Distorsioni nello scheduling dovute ai “blocked interrupts” Dal momento che lo scheduler KURT dipende dal tempo di arrivo degli interrupts e dal tempo necessario per realizzare accuratamente scheduling real-time dei tasks, è importante valutare l’effetto di avere interrupts disabilitati dai vari sottosistemi di Linux. Per fare ciò appunto, il kernel di Linux standard è stato modificato per stampare il tempo (utilizzando il Time Stamp Counter del Pentium)di tutti gli eventi in cui si verifica l’abilitazione o la disabilitazione degli interrupts. Questi dati vengono poi processati per trovare la durata di tempo entro la quale gli interrupts vengono disabilitati. La Tabella 7 elenca i sottosistemi, nonché i minimi, i massimi ed i medi intervalli all’interno dei quali gli interrupts vengono disabilitati in questi sottosistemi. Tabella 7 – Intervalli nei quali gli interrupts vengono disabilitati nel kernel di Linux Le figure 25 e 26 mostrano istogrammi in cui la percentuale degli eventi viene graficata in funzione degli intervalli temporali durante i quali gli interrupts sono disabilitati per quell’evento (si nota che la scala del grafico per il sottosistema disco non è la stessa degli altri sitemi). Come si può vedere dalla figura 25 (a), nel sottosistema “Console” di Linux la disabilitazione degli interrupts si verifica per periodi minori di 2µs. La massima durata è 12.13µs. Nel sottosistema “Network” di Linux, più disabilitazioni di interrupts si verificano per periodi minori di 2.5µs, e la massima durata è circa 2.74µs. 72 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Nel sottosistema “Disk” di Linux (figura 25(c)), la massima durata per la quale gli interrupts sono disabilitati è risultata essere 450µs. Fig. 25 – Durata della disabilitazione degli interrupts nei vari sottosistemi di Linux – I 73 Capitolo 4 Un’estensione firm real-time di Linux : il KURT Fig. 26 – Durata della disabilitazione degli interrupts nei vari sottosistemi di Linux – II Come si può osservare da queste misurazioni, più sottosistemi di Linux sono ragionevolmente adatti per applicazioni firm real-time. Per rendere Linux adatto per applicazioni hard real-time (ovvero applicazioni firm real-time molto più esigenti ), bisogna effettuare modifiche significanti al codice già esistente di Linux come ampiamente esposto nel capitolo 3. In particolar modo, il sottosistema disco bloccherebbe gli interrupts per periodi di tempo più lunghi, pertanto dovrebbe essere modificato prima che esso possa essere usato per realizzare applicazioni firm real-time particolarmente “esigenti”. Dal momento che l’intervallo durante il quale gli interrupts sono disabilitati è ampiamente dipendente dall’hardware utilizzato nel sistema, questi risultati non possono essere generalizzati e le misurazioni dovrebbero essere effettuate su un hardware “target” sotto una varietà di condizioni al fine di acquisire una migliore comprensione totale dell’idoneità del kernel di Linux a realizzare un sistema firm real74 Capitolo 4 Un’estensione firm real-time di Linux : il KURT time su quell’hardware (la velocità della CPU ha anche effetto sul tempo nel quale gli interrupts vengono disabilitati: pertanto è importante sottolineare che le misurazioni che sono state presentate in questo capitolo sono state effettuate su un processore Pentium da 133MHz ). Si dovrebbe anche notare che, eccetto l’intervallo durante il quale gli interrupts sono “blocked”, la frequenza con la quale essi si verificano rappresenta anche un fattore dal quale dipendono le performances di un sistema real-time. Ulteriori esperimenti necessitano di essere condotti per acquisire una migliore comprensione dell’effetto del “blocked interrupts” sulle prestazioni dello scheduler del KURT. 4.10 Diritti d’autore I diritti d’autore di questa piattaforma “firm real-time” si devono essenzialmente al Centro di Ricerche dell’Università del Kansas, che nel 1997 ha definito questo progetto. Questo software è stato sviluppato nello specifico dall’ Information and Telecommunication Technology Center (ITTC) dell’università del Kansas. Fondi parziali per la realizzazione di questo progetto sono state fornite dal gruppo Sprint. Questo software potrebbe essere usato e distribuito secondo i termini della licenza pubblica GNU, ma né l’ITTC né Sprint si prendono alcuna responsabilità per la distribuzione di questo prodotto. 75 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS 5.1 Introduzione Il sistema operativo che verrà descritto in questo capitolo, è il maggior rappresentante della famiglia degli RTOS per applicazioni specifiche (embedded) quali possono essere ad esempio, le reti di sensori. Un sistema operativo realizzato per tale ambito embedded, deve avere alcune caratteristiche di base: deve possedere ridotte dimensioni, basso consumo durante l’elaborazione, consumo pressoché nullo durante lo stato di idle, deve gestire la concorrenza, deve implementare protocolli di rete a seconda della periferica di rete utilizzata e tali protocolli devono essere poco dispendiosi in termini di energia (il TCP/IP e’ in genere inapplicabile); il sistema operativo, inoltre, deve fornire un’astrazione per i dispositivi hardware (sensori e attuatori) montati sul sensore. Si distinguono generalmente due approcci allo sviluppo di sistemi operativi per applicazioni embedded: • Sviluppare un sistema i cui componenti vengono compilati insieme all’applicazione (come TinyOS e BTnode system software)(figura 27). Questo di fatto consente una singola applicazione in esecuzione in un dato momento, tuttavia tale sistema permette di avere bassissimi consumi (non esistendo in genere context switch dal momento che gli scheduler seguono una politica run to completion) e sistemi molto piccoli (essendo realmente inserite nel sistema solo le funzionalità richieste, il core richiede solo 400 byte di dati). Lo svantaggio derivante da tale approccio è la limitata versatilità e i seri vincoli di riconfigurabilità dell’applicazione. 76 Capitolo 5 • TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS Sviluppare un sistema che includa i tradizionali strati di software dei sistemi general purpose in versione ridotta (ad esempio BerthaOS e MANTIS). In questo caso è difficile tenere i consumi e le risorse impiegate sotto controllo, ma si guadagna in versatilità potendo eseguire più applicazioni in contemporanea. Fig. 27 – Compilazione dei componenti insieme all’applicazione Di seguito verrà descritto nel dettaglio due di questi sistemi: TinyOS (attualmente il più affermato) e MANTIS. 5.2 TinyOS TinyOS è il sistema operativo di tipo “open-source” sviluppato dall’ università di Berkeley in California per la tecnologia motes. Attualmente, la versione più recente TinyOS 2.0, supporta le seguenti piattaforme: • • • • eyesIFXv2 intelmote2 mica2 mica2dot 77 Capitolo 5 • • • • TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS micaZ telosb tinynode btnode3 E’ scritto mediante nesC (è una variante del linguaggio C sviluppato per la programmazione dei motes: per alcuni versi può essere considerato un’ estensione del C in quanto implementa un modello ad eventi, per altri versi restringe il linguaggio C in quanto limita diverse operazioni riguardanti i puntatori) ed offre un modello di programmazione basato su eventi (l’applicazione è composta da diversi componenti la cui elaborazione viene avviata al verificarsi di un particolare evento). Questo approccio si contrappone al tradizionale paradigma basato su stack e switching del contesto di esecuzione. Quando il sistema è in stato di idle non esegue alcuna operazione, consumando minime quantità di energia. In questo modo pur permettendo la concorrenza, evita l’attività di context switching tipica dell’approccio tradizionale. Il componente principale (l’unico sempre presente in ogni applicazione) è lo scheduler, questo manda in esecuzione i task dei diversi componenti secondo una politica FIFO run to completion (un task non può interrompere un altro task). Lo scheduling ha due livelli di priorità: quello normale per i task e quello più alto per gli eventi, che possono interrompere i task (preemption). 5.2.1 I componenti Il modello a componenti di TinyOS (figura 28(b) è del tutto simile a quello di nesC (figur 28(a)). Esso è dotato di command handlers e event handlers. 78 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS (a) (b) Fig. 28 – (a) Rappresentazione di un componente di nesC; (b) Rappresentazione di un componente di TinyOS. E’ evidente la somiglianza con quelli di nesC, si possono anche qui riconoscere eventi e comandi, un componente include anche lo stato e diversi tasks I componenti comunicano tra loro invocando comandi (gestiti da command handlers) e sollevando eventi (gestiti da event handlers). Comandi ed eventi vengono eseguiti al livello alto di priorità dello scheduler. A questi si aggiunge una serie di task, che hanno lo stesso significato degli equivalenti in nesC e vengono eseguiti a livello basso di priorità. Ogni componente inoltre contiene un frame. Questa è l’area dati del componente e viene allocata staticamente. Tipicamente gli eventi vengono sollevati da componenti più vicini all’hardware verso componenti meno vicini, mentre i comandi vengono invocati in verso opposto. I componenti possono essere suddivisi in tre categorie (figura 29): 79 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS 1. Hardware abstractions, questi componenti mappano le funzionalità fornite via software sulle funzionalità fornite dall’hardware creando un’astrazione dello stesso utilizzabile dai moduli superiori; 2. Synthetic hardware, questi moduli simulano il comportamento di hardware più sofisticato di quello realmente presente sul sensore; 3. High level software component, questi componenti sono quelli di livello più alto e si occupano di eseguire algoritmi che prescindono dal particolare hardware. Ad esempio un componente che legge/scrive un bit su un canale radio è un’astrazione hardware, mentre un componente che compone 8 bit e li invia a quelli di livello superiore è un hardware sintetico, mentre il componente che implementa il protocollo di routing è un componente di alto livello. Fig. 29 - Livelli di astrazione per un sistema TinyOS 5.2.2 Split-phase operations In TinyOS ogni operazione non banale è una “split-phase operation”, ovvero la chiamata e l’operazione di ritorno sono in realtà due funzioni separate. Una funzione viene invocata chiamando un comando su un componente, questo avvia un task e ritorna 80 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS immediatamente. Alla terminazione del task viene sollevato un evento sul componente che ha invocato l’operazione. Un tipico esempio è l’invio di un pacchetto sulla rete. Ogni componente implementa una delle due metà delle operazioni split-phase previste (o il comando o l’evento). 5.2.3 Active messages “Active messages” è la tecnologia di rete utilizzata da TinyOS. E’ un’architettura che si avvicina molto a quella a comandi e componenti di programmazione del singolo sensore. Questo sistema permette di inviare messaggi a tutti o a un singolo nodo tra i nodi vicini (protocolli di routing sono implementati ai livelli superiori, quindi ha solo un meccanismo di indirizzamento verso i nodi vicini). Active messages è una tecnologia molto leggera, infatti non specifica meccanismi connection oriented, ogni pacchetto è un’entità indipendente. Esso contiene l’identificatore di un handler da richiamare sulla macchina di destinazione e il payload del pacchetto. Questo sistema permette di evitare il complesso utilizzo di buffer delle implementazioni del protocollo TCP/IP. Il principale svantaggio dell’approccio è che tutti i nodi comunicanti devono avere lo stesso software o quantomeno implementare un componente che definisca lo stesso handler. 5.2.4 Miglioramento dello scheduler della versione 1.0 : soluzione all’overload con l’introduzione del concetto di priorità Quando il rate di arrivo degli interrupts è molto alto, la CPU non è capace di eseguire alcun task diversamente dagli interrupt handlers. Questa situazione fa riferimento in particolar modo al problema dell’overload dei sistemi operativi. Il rate attraverso il quale il sistema è capace di completare i suoi tasks è minore del rate dei tasks entranti, in tal maniera c’è un momento in cui la coda dei tasks entranti si mantiene crescente finchè non possono essere processati dal sistema più richieste o tasks. Il rate per il rilevamento o il campionamento dei dati, può essere invece controllato essendo sostanzialmente un task localizzato. Comunque, il traffico entrante per il routing dei 81 Capitolo 5 dati, TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS rappresenta qualcosa che potrebbe portare al problema dell’overload sopra menzionato. La CPU crea pacchetti per processi, ma non è capace di processare i tasks che sono stati posizionati nelle varie code. In altri termini essa non è capace di inoltrare alcun pacchetto. La figura 30 mostra come la resa dei pacchetti (throughput) si riduca in presenza di un task locale ad 8Hz (125 ms) con tempi di esecuzione variabili all’interno di una piattaforma TinyOS 1.0. Non appena il tempo di esecuzione di un task locale aumenta, il throughput dei pacchetti radio diminuisce sensibilmente. Fig. 30 – Il throughput dei pacchetti si riduce in presenza di tasks locali In TinyOS 1.x quindi, c’è una coda condivisa da tutti i tasks, ed un componente può eseguire un task più volte. Se la task-queue è piena l’esecuzione dell’operazione fallisce. L’esperienza con gli stacks di rete si dimostra alquanto problematica, viceversa il task potrebbe segnalare il completamento di un operazione split-phase: se l’esecuzione fallisce, il componente di sopra potrebbe bloccarsi continuamente, aspettando il completamento dell’evento. E’ importante sottolineare quindi, come lo scheduler del TinyOS 1.0 utilizzi una coda FIFO per lo scheduling di tutti i tasks, così facendo tutti i tasks vengono trattati come se avessero la stessa importanza. Una delle tante possibili soluzioni al problema della diminuzione del throughput in caso di overload del sistema (perché magari è in esecuzione un task locale, e quindi il processamento di tale pacchetto bloccherebbe completamente un nodo sensore), è stata proposta dal Department of Computer Science dell’università di Washington che suggerisce di introdurre il concetto di “priorità per i tasks” (si osservi a tal proposito la 82 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS figura 31) per differenziare i tasks “importanti”(tasks real-time) da quelli che hanno meno rilevanza (tasks ordinari). Fig. 31 – Miglioramento del throughput relativo ai pacchetti spediti mediate l’uso della priorità Come mostrato in figura, l’aggiunta della priorità per i tasks migliora sostanzialmente il throughput. Tale soluzione ha ricevuto molto successo ed è stata utilizzata per programmare lo scheduler della recente versione TinyOS 2.0. In TinyOS 2.x infatti, ogni task possiede il suo proprio slot riservato all’interno della task-queue, ed un task può essere eseguito solo una volta. Un’esecuzione fallisce se e solo se un task è gia stato assegnato. Se un componente necessita di eseguire un task più volte, esso può settare una variabile di stato interna così che non appena il task viene eseguito, esso viene riassegnato. 5.3 Mantis OS Mantis OS è il sistema operativo della piattaforma MANTIS che si basa sui sensori nymph. Concettualmente MANTIS è opposto a TinyOS, infatti esso ha la struttura di un sistema operativo general purpose, è organizzato in livelli, è multithread e contiene uno scheduler preemptive con time slicing, meccanismi di sincronizzazione attraverso sezioni in mutua esclusione, uno stack protocollare standard per la rete e device drivers (figura 32). 83 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS Fig. 32 – Architettura del sistema Mantis OS. Si nota la somiglianza con i sistemi UNIX. Il componente command server permette di amministrare da remoto il singolo sensore attraverso una shell UNIX-like Questo approccio accelera l’apprendimento della nuova tecnologia e aumenta la versatilità, ma pone seri problemi di prestazioni e di consumi. 5.3.1 Kernel e scheduler Le funzionalità offerte dal kernel di MANTIS OS sono un sottoinsieme dell’interfaccia POSIX, in particolare lo scheduler priority-based (secondo l’algoritmo round-robin). Per la sincronizzazione e la concorrenza il sistema supporta semafori sempre secondo lo standard posix. La memoria RAM è divisa in due sezioni: statica, dove vengono allocate al momento della compilazione le varabili globali; heap, dove vengono allocati i thread al momento dell’esecuzione. Non è possibile allocare manualmente memoria dinamica al momento. 5.3.2 Stack protocollare Per quanto riguarda la comunicazione di rete, MANTIS OS prevede uno stack protocollare strutturato su quattro livelli: fisico, MAC, network e applicazione. Il 84 Capitolo 5 TinyOS e Mantis: uno sguardo all’immediato futuro degli RTOS sistema è molto più sofisticato e versatile di quello di TinyOS, infatti possono coesistere meccanismi di routing diversi (unicast, flooding, multicast). I diversi livelli sono in esecuzione in thread separati, con l’eccezione del livello fisico e MAC che vengono eseguiti dallo stesso processo. La lettura di un pacchetto di rete funziona con un sistema stop and wait. Qui un thread intenzionato a leggere un pacchetto dalla rete (tramite chiamata a mos_recv) rimane bloccato su un semaforo. Quando un pacchetto arriva viene sollevato un interrupt, il device driver quindi sblocca il semaforo. Non esiste il concetto di connessione: l’invio e il routine vengono sempre effettuati per ogni singolo pacchetto separatamente. Questo approccio rende l’interfaccia di rete più versatile, infatti il progettista del software può sviluppare l’applicazione senza essere a conoscenza dei meccanismi di routing usati nella particolare rete sviluppata; inoltre è molto utile per la riprogrammazione dinamica del sensore, in quanto per riprogrammare le funzionalità di rete è sufficiente fermare i thread dello stack in esecuzione e eseguire i thread del nuovo stack protocollare. Di contro questo sistema è prestazionalmente più scadente di Active Messages, essendo l’elaborazione del singolo pacchetto più lunga, e comportando un continuo scambio di contesto di esecuzione al momento della comunicazione di rete. Questo causa consumi maggiori. 85 Capitolo 6 Conclusioni sullo studio dei sistemi operativi real-time Capitolo 6 Conclusioni sullo studio dei sistemi operativi real-time 6.1 Considerazioni finali Le versioni real-time di Linux, analizzate nel seguente elaborato, differiscono molto sia nel “come”essi riescono a risolvere i problemi real-time sia nel “quanto” essi riescano a farlo più o meno bene. Le soluzioni, adottate dai vari sistemi, differiscono sia nella durata dell’intervallo del tempo di risposta garantito, che nelle situazioni in cui essi garantiscono le performances. Molti sviluppatori di software, preferiscono che le loro applicazioni vengano eseguite nello user-space invece che nel kernel-space. Tanti approcci al real-time richiedono che il codice venga eseguito all’interno del kernel-space. Il codice che viene eseguito nel kernel-space, se confrontato con quello eseguito all’interno dello user-space, è spesso più difficile da debuggare, è più probabile che si verifichi un crash all’interno del sistema, ed è meno conveniente realizzare la comunicazione tra i tasks dello user-space. La scelta del kernel-space, però, viene generalmente fatta fuori dal desiderio di evitare i ritardi che il kernel di Linux potrebbe imporre ad i programmi dello user-space. Due approcci (di natura “hard real-time”) al kernel-space real-time analizzati in questo elaborato sono l’RTLinux e l’RTAI. Si è poi proceduto alla descrizione di un ulteriore approccio “firm” real-time attraverso l’analisi dell’RTOS KURT sviluppato all’Università del Kansas, ed infine è stata anche fatta una panoramica su due dei più importanti sistemi operativi real-time “embedded” che nascono per esigenze specifiche, ovvero il TinyOS ed il Mantis OS. E’ importante sottolineare che i sistemi operativi real-time analizzati in tale ambito, sono solo alcuni dei più importanti ed innovativi RTOS descritti nel capitolo 2, ma non costituiscono affatto l’intera descrizione del problema. Come ultimo scopo del mio lavoro, dopo aver attuato un confronto ove possibile (ad esempio tra i due RTOS hard, 86 Capitolo 6 Conclusioni sullo studio dei sistemi operativi real-time ossia RTLinux ed RTAI), ho cercato infine di accumunare il più possibile le caratteristiche di tutti i sistemi RTOS (qui analizzati e non), per valutarne le differenze strutturali e per realizzare una tabella riassuntiva che potesse permettere un immediato confronto delle caratteristiche teniche dei vari OS all’interno di un contesto specificatamente “real-time”(Tabella 8). Tabella 8 – Principali caratteristiche dei vari RTOS commerciali ed “open source” Dall’analisi di tale tabella si deduce che per realizzare alcune particolari caratteristiche ci sono differenti approcci. Per esempio, MontaVista, RED-Linux, e TimeSys presentano tutti schedulers rimpiazzati in Linux per permettere l’analisi dei tasks dello user-space. In tal modo, osservando la natura degli ingressi, si consente un immediato riscontro o meno della caratteristica real-time desiderata nel sistema operativo di interesse. Il significato di tali ingressi è qui descritto: • Separate real-time kernel : significa che un differente sistema operativo è chiamato a gestire interrupts e dispositivi, e questo sistema operativo esegue Linux come se fosse un task separato; 87 Capitolo 6 • Conclusioni sullo studio dei sistemi operativi real-time User space programming : significa che un’applicazione può avere tasks realtime in esecuzione nello user-space; • Improved Linux kernel preemption : gli sviluppatori hanno modificato il kernel di Linux al fine di accorciare i periodi nei quali il kernel potrebbe non essere prelazionato; • “Fully preemptible” Linux kernel : gli sviluppatori hanno modificato il kernel di Linux affinché possa esser prelazionato a meno che il kernel stesso vieti specificatamente ciò, piuttosto che utilizzare il normale kernel il quale potrebbe essere prelazionato solo quando il kernel lo permette specificatamente; • Precise scheduling within Linux : significa che i processi a priorità più alta prelazionano immediatamente quelli a priorità più bassa. Si nota che con Linux standard altri fattori vengono presi in considerazione oltre alla priorità; • Solution for priority inversion within Linux : gli sviluppatori hanno fornito un mezzo per evitare che un task ad alta priorità attenda “bloccato” l’esecuzione di un task a più bassa priorità. Si nota che gli FSMLabs consentono di ereditare la priorità (inheritance) e consigliano agli sviluppatori di evitare le situazioni dove il suo uso sarebbe necessario; • “Fast” interrupt response, < 1ms : sta a significare che i tasks scritti in modo appropriato dovrebbero essere realmente iniziati all’esecuzione dal sistema entro 1ms seguente alla ricezione dell’interrupt dell’ hardware associato. Si nota che per RTAI ed RTLinux questo tempo potrebbe essere molto maggiore, anche dell’ordine dei 15µs; • “Moderate ” interrupt response, < 5ms : sta a significare che i tasks scritti in modo appropriato dovrebbero essere realmente iniziati all’esecuzione dal sistema entro 5ms seguenti alla ricezione dell’interrupt dell’hardware associato. Questo tempo di risposta è sufficiente per molte applicazioni, come ad esempio per le applicazioni audio; 88 Capitolo 6 • Conclusioni sullo studio dei sistemi operativi real-time Improved precision for time/timers witin Linux : precisa l’esistenza di un metodo alternativo che è più preciso della risoluzione standard di 10ms. TimeSys Linux/RT non fa altro che aggiungere proprietà real-time a Linux per mezzo di un “resurce kernel”(RK), che viene implementato come un modulo caricabile. Questo modulo fornisce uno standard API che i tasks dello user-space possono utilizzare per migliorare la propria preemption, per aver uno scheduling più preciso, per evitare il fenomeno dell’inversione di priorità, e per migliorare il proprio tempismo. All’interno della tabella, il termine “within RK” sta ad indicare che la proprietà desiderata è fornita per mezzo di system calls dell’API all’interno del resurce kernel, da momento che queste beneficiano di una migliore preemption. La notazione “with RK, without RTAI” indica che essa altro non è che una proprietà fornita ai tasks che fa uso della API RK, ma che non può far uso di RK(e della sua API) se si sta gia utilizzando RTAI, dal momento che i due complementi sono mutuamente esclusivi. Si può scorgere, sempre osservando la tabella, che non c’è un singolo prodotto che offra un set “all-inclusive” di proprietà real-time. In conseguenza di ciò, parecchie società offrono tecnologie alternative mutiple (come più miglioramenti per lo scheduler nelle versioni di RTLinux ed RTAI) in maniera da soddisfare un range sicuramente più ampio di esigenze real-time. Infine allo scopo di evidenziare le proprietà degli OS “embedded” analizzati nel capitolo 5 , ho provveduto a realizzare tabelle esemplificative che racchiudessero al loro interno le caratteristiche salienti di questi sistemi operativi “event-driven” rispetto a quelle che sono le tradizionali caratteristiche dei sistemi “general purpose”. In Tabella 9 è possibile osservare un primo confronto generale. 89 Capitolo 6 Conclusioni sullo studio dei sistemi operativi real-time Caratteristiche General purpose OS Event-driven OS Models of Computation(MOC) Multi-tasking Comunicazione macchine a tra stati finiti estese (EFSM) Scopo d’uso Generale Rivolto a sistemi event-driven Costi di comunicazione Alti Bassi Frequenza di comunicazione Bassa Alta Richiesta di memoria Ampia Bassa Tabella 9 – Confronto generale tra le caratteristiche degli OS “general purpose” e quelle degli “event-driven” In Tabella 10 è invece possibile osservare il confronto tra la diversa richiesta di memoria tra le due differenti politiche di OS. OS type Processore Applicazione Memoria Memoria totale dati istruzioni General ARM7 thumb 10.096 22324 54988 Event-driven ARM7 thumb 5312 8000 2800 Event-driven 8 bit RISC 2740 3176 709 Purpose Tabella 10 – Confronto tra le richieste di memoria Con la medesima scelta del processore(ARM7 a 16 bit), TinyOS necessita di metà memoria istruzioni e di circa un trentesimo di memoria dati. Gli studi dimostrano che il consumo di potenza di una SRAM scala approssimativamente con la radice quadrata della capacità. Questo significa che in TinyOS la potenza della memoria istruzioni può essere ridotta di 1.6x e quella della memoria dati rispettivamente di 4.2x. Utilizzando un più semplice processore come quello RISC a 8-bit, si potrebbe ulteriormente ridurre la dimensione della memoria ed il consumo di potenza. 90 Capitolo 6 Conclusioni sullo studio dei sistemi operativi real-time La figura 33 mostra invece un confronto tra le performances delle due diverse piattaforme. Fig. 33 – General-purpose OS contro event-driven OS. Il riquadro a destra identifica i componenti del sistema. Il grafico di sinistra confronta il conteggio dei cicli totali del processore: ben 16365 del general purpose contro i 2554 del TinyOS. Quest’ultimo sistema “embedded” mostra un fattore di ben 8 miglioramenti, che si traduce direttamente in un fattore di 8 riduzioni nel consumo di potenza del processore. Il grafico di destra confronta invece i costi dei due OS (le porzioni piu basse della barra) in termini di percentuale dei cicli totali. Come indicazione della propria inefficienza, il sistema operativo general- purpose presenta un costo di OS pari all’86% mentre TinyOS circa del 10%. Come esempio chiarificatore potremmo stimare quanta potenza viene realmente risparmiata considerando sia il processore che i suoi blocchi di memoria. Con una tecnologia di 0.18µm e con una tensione di 1.8V, un processore ARM7 consuma circa 0.25mW/MHz. Per una memoria di dimensione pari a 64KB per l’acceso alla lettura si consuma circa 0.407mW/MHz mentre per l’accesso alla scrittura circa 0.447mW/MHz. Se si suppone che il 10% delle istruzioni coinvolgono le operazioni di lettura da memoria ed il 10% quelle di scrittura e di allocazione della memoria, oltre alla scalatura del conteggio del ciclo del processore, il consumo di potenza dei due OSs sono rispettivamente: 0.608mW/MHz e 0.053mW/MHz. Cioè, in altri termini, TinyOS presenta un fattore di miglioramento di potenza pari a 12. Si potrebbe sostenere che il general-purpose OS rappresenti un’esagerazione e potrebbe esser ottimizzato per dare migliori performances e una migliore potenza. Essendo il 91 Capitolo 6 Conclusioni sullo studio dei sistemi operativi real-time general-purpose un OS riconfigurabile, gli sviluppatori scelgono ovviamente le opzioni di configurazione che forniscono la più piccola e la più semplice implementazione. Un’ulteriore ottimizzazione invece, si potrebbe avere applicando un fattore 12 alla potenza, ma anche in questo caso le prestazioni del TinyOS dovrebbero rimanere di molto superiori. 92 Bibliografia Bibliografia 1) Giorgio C. Buttazzo “Hard Real-Time Computing Systems Predictable Scheduling Algorithms and Applications”, Kluwer Academic Publishers; 2) Doug Abbott “Linux for Embedded and Real-Time Applications”, Newnes; 3) Giuseppe Montano “Linux e il real-time in applicazioni spaziali”, Seminario nell’ambito del corso di Sistemi Operativi in Tempo Reale tenuto dal Prof. Aldo Franco Dragoni; 4) Victor Yodaiken, New Mexico Institute of Technology(Oct. 7, 1997) “An Introduction to RTLinux”; 5) P. Mantegazza, E. Bianchi, L. Dozio, S. Papacharalambous, S. Hughes, D. Beal (Apr. 6, 2000) “RTAI: Real-Time Application Interface”; 6) Linuxdevices.com (Last updated: Nov. 19, 1999) “RTLinux -- a hard real-time Linux add-on”; 7) Peter Laurich (Nov. 19, 2004) “A comparison of hard real-time Linux alternatives” Linuxdevices.com; 8) Kevin Dankwardt, of K Computing (Updated Oct. 11, 2000) “Comparing realtime Linux alternatives” Linuxdevices.com; . 9) E. Bianchi, L. Dozio, P. Mantegazza “A Hard Real Time support for Linux”, Dipartimento di Ingegneria Aerospaziale, Politecnico di Milano; 93 Bibliografia 10) KURT Project, University of Kansas (Mar. 24, 2000) “KURT: The KU RealTime Linux”; 11) Robert Hill, Balaji Srinivasan, Shyam Pather, e Douglas Niehaus “Temporal Resolution and Real-Time Extensions to Linux”, Information and Telecommunication Technology Center Department of Electrical Engineering and Computer Sciences University of Kansas June 3, 1998; 12) Will Dinkel, Douglas Niehaus, Michael Frisbie, Jacob Woltersdorf “KURTLinux User Manual” Information and Telecommunication Technology Center University of Kansas March 29, 2002; 13) Filippo Pacifici “Metodologie per la realizzazione di software per reti di sensori” Dipartimento di Elettronica e Informazione del Politecnico di Milano; 14) Philip Levis “TinyOS 2.0 Overview” Feb 8, 2006 Linuxdevices.com; 15) Suet-Fei Li, Roy Sutton and Jan Rabaey “Low Power Operating System for Heterogeneous Wireless Communication Systems”, Department of Electrical Engineering and Computer Science University of California at Berkeley; 16) Venkita Subramonian, Huang-Ming Huang, Seema Datar, Chenyang Lu “Priority Scheduling in TinyOS - A Case Study”, Department of Computer Science Washington University St. Louis. MO December 16, 2002; 17) Andrea Zanella, Michele Zorzi “Reti di Sensori: dalla teoria alla pratica”, SIGNET (Special Interest Group on NETworking) presso il Dipartimento di Ingegneria dell’Informazione dell’Università di Padova; 94