Analisi del Sistema Operativo RTEMS per lo sviluppo di applicazioni

Scuola Politecnica e delle Scienze di Base
Corso di Laurea in Ingegneria Informatica
Elaborato finale in Sistemi Real Time
Analisi del Sistema Operativo RTEMS per
lo sviluppo di applicazioni Real Time
Anno Accademico 2013/2014
Candidato:
Emanuele Capone
matr. N46001016
Alla mia famiglia,
per avermi dato un’enorme
possibilità.
Indice
Indice .................................................................................................................................................. III Introduzione ......................................................................................................................................... 4 Capitolo 1: Architettura Interna ........................................................................................................... 6 1.1 Classificazione Resources Manager........................................................................................... 7 Capitolo 2: Scheduler ......................................................................................................................... 12
2.1 Deterministic Priority Scheduler .............................................................................................. 13
2.2 Simple Priority Scheduler ........................................................................................................ 14 2.3 Simple SMP Priority Scheduler ............................................................................................... 14 2.4 Earliest Deadline First Scheduler ............................................................................................. 15 2.5 Constant Bandwidth Server Scheduler .................................................................................... 16 Capitolo 3: Ciclo di vita dei task ........................................................................................................ 19
3.1 Condizioni di blocco/sblocco di un task .................................................................................. 21 Capitolo 4: RTEMS in ambiti applicativi .......................................................................................... 24
4.1 Solar Dynamic Observatory ..................................................................................................... 24
4.2 Electra ...................................................................................................................................... 26 Conclusioni ........................................................................................................................................ 27 Bibliografia ........................................................................................................................................ 28 Introduzione
RTEMS, acronimo di Real-Time Executive for Multiprocessor Systems, è un sistema
operativo Real-Time distribuito in modalità Open Source e attualmente gestito dalla OAR
corporation in collaborazione con la comunità di sviluppatori che lo supportano. RTEMS è
stato progettato per sistemi embedded, ma nel corso dei suoi undici anni di vita ha trovato
un utilizzo pratico in numerosi progetti e applicazioni mission critical in ambito industriale,
medico, spaziale e su una vasta gamma di architetture hardware come ARM, Intel, MIPS,
PowerPC e molte altre. Una delle particolarità di questo sistema operativo è il supporto a
diversi standard quali POSIX e ITRON, oltre alla compatibilità con numerose Application
Program Interface di tipo open. Tra le principali caratteristiche di funzionamento di
RTEMS c’è di sicuro il supporto al multitasking, al multiprocessore (così come suggerisce
l’acronimo), la possibilità di avere a nostra disposizione scheduling priority-based e
preemptive, il supporto all’allocazione dinamica della memoria, la presenza di un rate
monotonic scheduling e molto altro che analizzeremo nel corso dell’elaborato.
In linea generale, RTEMS, essendo un sistema operativo real-time deve soddisfare dei
vincoli temporali ben precisi: in sintesi possiamo dire che la correttezza di funzionamento
in questo caso dipende non solo dalla validità dei risultati prodotti, ma anche dal tempo in
cui essi vengono restituiti, da qui si arriva a parlare di sistemi dal doppio concetto di
correttezza, sia logico che temporale. Il termine “Real” invece sta a indicare che la risposta
di un sistema Real-Time a eventi esterni ad esso deve avvenire durante l’evolversi degli
eventi stessi, quindi il tempo interno del sistema e quello dell’ambiente in cui opera
4
dovranno necessariamente essere misurati con lo stesso riferimento.
Uno dei punti cardini sui quali si basa la filosofia di sviluppo di RTEMS è l’essere quasi del
tutto Open Source. Il codice sorgente, infatti, è costituito da una collezione di software con
licenze di tipo free, che possono essere utilizzati liberamente da sviluppatori di software
proprietari senza richiedere particolari vincoli di licenza sull’applicativo finale. In altre
parole chiunque può modificare ed eventualmente ridistribuire il codice di RTEMS
rispettando i termini della General Public License (GPL modified) pubblicata dalla Free
Software Foundation, ma eventualmente con la possibilità di includere particolari header o
templates per la produzione di un eseguibile che non verrà distribuito con licenza GPL, ma
ad esempio con licenza proprietaria. Tuttavia come spesso accade con i software Open
Source, anche RTEMS è distribuito con la speranza di essere utile ai fini di un progetto che
lo richiede, ma senza alcun tipo di garanzia sul suo corretto funzionamento in seguito a
modifiche o addirittura utilizzato in accoppiata con determinati tipi di software.
Ovviamente il tipo di distribuzione Open Source ha permesso a numerosi progetti, sia
indipendenti che sovvenzionati da grandi aziende, di usufruire dei servizi di questo
importante sistema Real Time, contribuendo alla crescita di RTEMS insieme alla stessa
OAR Corporation (On-Line Applications Research), in questo momento a capo della
gestione del progetto.
Durante l’elaborato saranno presi in considerazione i principali aspetti di questo sistema
operativo, soffermandosi dapprima sull’architettura interna del sistema, per poi passare a
un’analisi approfondita del comportamento dei processi, con il ciclo di vita dei task e gli
scheduler utilizzati per la gestione degli stessi, chiudendo infine con una breve disamina
degli ambiti applicativi in cui RTEMS è utilizzato, fornendo alcuni esempi interessanti di
progetti pratici in via di sviluppo o abbastanza recenti.
5
Capitolo 1: Architettura interna
Prima di partire con l’analisi del funzionamento vero e proprio di questo sistema e la
gestione dei task real-time, è interessante andare ad osservare il modo in cui è stato
concepito RTEMS, vale a dire la sua architettura interna e il modo in cui i vari componenti
collaborano tra loro per fornire funzionalità agli sviluppatori di applicazioni e progetti.
Volendo studiare l’architettura dell’OS come un qualsiasi sistema General Purpose, vale a
dire sotto forma di strati sovrapposti, anche RTEMS può essere rappresentato come una
sorta di strato software intermedio tra il livello hardware e quello applicativo. Chiaramente
viene fornita un’interfaccia del kernel al livello applicativo formata dalle cosiddette
“RTEMS API Calls”, raggruppate a loro volta in moduli chiamati resource managers,
ciascuno dei quali è responsabile della fornitura di servizi specifici per il funzionamento
generale del sistema. Il tutto è coordinato da un nucleo centrale chiamato RTEMS Core
che comprende le varie routine necessarie per interfacciarsi con la CPU, e risulta di fatto il
maggior responsabile della gestione del sistema a basso livello e dei drivers dei dispositivi,
tutti i vari manager chiaramente non potrebbero funzionare correttamente senza la
presenza di questo nucleo coordinatore. Da un punto di vista concettuale (così com’è ben
visibile in Figura 1) potremmo vedere la struttura di RTEMS come una torta il cui centro è
caratterizzato dal nucleo del sistema, ciascuna fetta è un modulo che è possibile richiamare
a livello applicativo attraverso le API messe a disposizione.
6
1.1 Classificazione Resources Manager
All’interno di questo paragrafo è presente una breve disamina per i vari manager che
supportano il sistema operativo, i quali vengono raggruppati per tipologia e scopi
funzionali, ciascuno con le proprie caratteristiche e le direttive utilizzabili per la fruizione
di determinati servizi. Ogni manager è fondamentale per RTEMS, tuttavia è stata posta
particolare attenzione nei confronti di alcune componenti come il Semaphore Manager o il
Rate Monotonic Manager, che hanno compiti più onerosi.
Figura 1: Struttura Managers
Manager che si occupano delle politiche di gestione e temporali dei task
-
L’Initialization Manager è il responsabile dell’avvio e lo spegnimento di RTEMS, più
precisamente si occupa della creazione e l’avvio dei task d’inizializzazione e invoca le varie
routine per l’inizializzazione dei driver di periferica. In caso di sistemi multiprocessore il
manager si occupa di inizializzare anche l’interprocessor communication layer.
-
Il Task Manager raggruppa una serie di direttive per amministrare, creare ed
eventualmente eliminare task come ad esempio rtems_task_create (crea un task),
7
rtems_task_start (avvia un task) e rtems_task_set_priority (imposta la priorità di un task).
-
L’Interrupt Manager, invece, si occupa di fornire meccanismi di risposta a interrupt
generate esternamente, in maniera tale da soddisfare i vincoli temporali dell’applicazione. Il
manager in questione permette tempi di risposta alle interrupt molto rapidi, alterando la
normale esecuzione e facendo in modo che un task sia prelazionato all’uscita di un processo
da un ISR (Interrupt Service Routine).
-
Tra i manager dedicati alla gestione delle politiche temporali, c’è il Timer Manager, il
quale non fa altro che fornire supporto per le funzionalità di temporizzazione più generiche,
con direttive quali rtems_timer_create (Crea un timer), rtems_timer_delete (elimina un
timer esistente) e molte altre.
-
Il Clock Manager si occupa sempre di funzionalità legate alla gestione temporale, ma in
maniera più specifica, attraverso direttive del tipo rtems_clock_set (per importare data e
ora), rtems_clock_get_uptime (restituisce il tempo trascorso dall’avvio) e molte altre.
-
Infine fa parte di questa categoria il Fatal Error Manager, un elemento fondamentale che
riesce a gestire gli errori fatali o irrecuperabili, oppure semplicemente le classiche
terminazioni di sistema.
Manager che si occupano di sincronizzare gli eventi tra i vari task
-
Il Semaphore Manager è un componente imprescindibile del sistema, giacché fornisce i
meccanismi basati sull’algoritmo di Dijkstra per l’implementazione di semafori e
conseguente supporto alla sincronizzazione e mutua esclusione dei processi in esecuzione.
Mette a disposizione, quindi, tutte le direttive necessarie per la creazione, la rimozione e il
rilascio dei semafori. Grazie a questo manager, infatti, viene implementato il meccanismo
di Priority Inheritance per risolvere il problema di inversione di priorità, assegnando al task
8
che detiene una risorsa la priorità più alta tra i processi in attesa dello sblocco di quella
stessa risorsa, in questo modo non c’è il rischio che un task a priorità intermedia possa
eseguire prima del processo a priorità più alta che è stato precedentemente bloccato. In
realtà RTEMS implementa anche Priority Ceiling, un altro protocollo capace di risolvere lo
stesso problema ma in maniera differente, introducendo un ceiling per ogni risorsa protetta,
definito come la massima tra le priorità dei task che potrebbero usare e conseguentemente
bloccarsi su quella determinata risorsa; a questo punto un processo potrà eseguire se e solo
se la sua priorità è strettamente maggiore del massimo tra i ceiling delle risorse attualmente
occupate.
-
Il Message Manager, invece, si occupa di gestire la comunicazione tra i vari processi e la
necessaria sincronizzazione mediante l’uso di code di messaggi in RTEMS. Le direttive
utilizzate in questo caso sono del tipo rtems_message_queue_create/delete/broadcast
(rispettivamente per creare, eliminare una coda, oppure per inviare un messaggio in
broadcast) con l’ultimo termine che cambia in base alla funzione voluta.
-
L’Event Manager è quel gestore capace di fornire un metodo a elevate prestazioni per la
sincronizzazione e la comunicazione tra task all’interno del sistema. In questo caso le
direttive utilizzate sono solamente due, rtems_event_send e rtems_event_receive.
-
Chiudendo con l’analisi sui gestori dedicati alla sincronizzazione, bisogna citare il Signal
Manager, elemento che fornisce le funzioni necessarie per la comunicazione asincrona tra
task, che si basa come ben sappiamo sull’invio di un messaggio o un semplice segnale
senza attendere risposta, continuando l’esecuzione. Anche in questo caso le direttive
utilizzabili sono solamente due, rtems_signal_catch (per stabilire un ASR) e
rtems_signal_send (per inviare un segnale ad un task).
9
Manager responsabili della gestione della memoria
-
Il Partition Manager fornisce tutto il necessario per riuscire ad allocare dinamicamente la
memoria a disposizione in unità dalle dimensioni prefissate. Le direttive utilizzabili sono
del tipo rtems_partition_create/ident/delete etc. con l’ultima parola che varia in base alla
funzione richiesta.
-
Il Region Manager invece ha una funzione abbastanza simile al Partition Manager, in
questo caso però il gestore fornisce ancora funzioni per allocare dinamicamente la memoria,
questa volta però in unità di dimensione variabile. Alle direttive di Partition Manager basta
sostituire “partition” con “region” per il resto sono abbastanza simili in quanto a
funzionalità.
-
Il Dual Ported Memory Manager: fornisce i meccanismi necessari per convertire gli
indirizzi tra rappresentazione interna ed esterna per aree di memoria Dual-Ported multiple.
Tra le direttive utilizzabili troviamo rtems_port_create, rtems_port_delete e soprattutto
rtems_port_external_to_internal/internal_to_external.
Manager che implementano le altre funzionalità necessarie
-
L’I/O Manager fornisce un particolare meccanismo per l’accesso ai driver dei dispositivi e
una metodologia per organizzare gli stessi driver. Tra le direttive utilizzabili ci sono
rtems_io_initialize (per inizializzare un driver), rtems_io_open/close (per aprire o chiudere
la connessione con un dispositivo di I/O) e rtems_io_read/write (per scrivere o leggere da
un dispositivo).
-
Il Rate Monotonic Manager ha un’importanza cruciale per il funzionamento del sistema, il
tutto sarà chiarito all’interno del capitolo dedicato agli scheduler, ma in linea generale
10
possiamo dire che si occupa di implementare l’omonimo algoritmo per la schedulazione di
task periodici. Permette inoltre di avere informazioni riguardo l’esecuzione di questi
periodi, restituendo statistiche che possono risultare utili all’utente per la sua applicazione.
Anche in questo caso ovviamente abbiamo numerose direttive per la gestione dei periodi e
delle statistiche.
-
L’User Extensions Manager si occupa di fornire gli strumenti adatti per permettere allo
sviluppatore di un’applicazione di estendere il suo software, dandogli la possibilità di
utilizzare routine aggiuntive invocate in corrispondenza di eventi critici di sistema.
-
Il Multiprocessing Manager fornisce, infine, tutto il necessario per la gestione di RTEMS
con sistemi multiprocessore. Il manager è stato introdotto per aumentare l’efficienza del
sistema operativo, poiché grazie ad esso, su piattaforme aventi diversi processori, è
possibile condividere dati e risorse globali tra le diverse CPU, aumentando però la
complessità della gestione generale del sistema, in quanto parliamo pur sempre di un
sistema real-time.
11
Capitolo 2: Scheduler
Gli scheduler sono una parte fondamentale di un qualsiasi sistema operativo, giacché il
loro compito è scegliere quali processi mandare in esecuzione tra quelli presenti nella coda
dei processi pronti, utilizzando opportuni algoritmi in base alle esigenze e alle condizioni
del sistema in esecuzione. Com’è facile intuire, essi assumono un’importanza ancora
maggiore nell’ambito dei sistemi real-time, poiché devono riuscire a gestire ed organizzare
l’esecuzione dei vari task in modo tale da assicurare che ognuno di essi termini entro la
propria deadline, quindi anche in questo caso il tutto ruota attorno ai requisiti temporali di
ogni processo. La deadline non è altro che il tempo massimo entro cui un processo realtime deve terminare la propria esecuzione, spesso, infatti, la violazione di questo fattore
può portare ad eventi catastrofici se abbiamo a che fare con task hard real-time, altrimenti
con processi di tipo soft può essere causa di un degrado delle prestazioni.
Dalla versione 4.10 RTEMS prevede cinque tipi diversi di scheduler priority based,
chiamati in questo modo poiché assicurano che il task in esecuzione in qualsiasi momento
è sempre quello a priorità più alta, ovviamente tra quelli presenti nella coda dei processi
pronti. La possibilità di supportare diversi algoritmi, inoltre, la cui implementazione
risiede all’interno dell’RTEMSCore, è data da un plugin framework previsto in RTEMS:
l’utente in questo modo può decidere quale tipo di scheduling utilizzare tra quelli presenti,
in base alle proprie esigenze di sviluppo, oppure implementarne uno proprio e configurarlo
con il sistema. Se non ci sono configurazioni da parte dell’utente, di default RTEMS per i
sistemi single core fa uso di Deterministic Priority Scheduler, algoritmo presente fin dalla
prima versione del sistema operativo e l’unico utilizzabile fino alla versione 4.10. Ad esso
12
si sono poi aggiunte le variazioni conosciute come SPS e SSMP e due algoritmi
particolarmente famosi utilizzati in molti altri sistemi real-time sui quali sono presenti
alcuni approfondimenti, vale a dire EDF e CBS.
Una volta che lo scheduling utilizzato decide quale task mandare in esecuzione entra in
atto il dispatcher, elemento presente anche in RTEMS e responsabile dell’assegnazione
della CPU ad un particolare task pronto, in altre parole è colui che si occupa fisicamente di
mandare in esecuzione un processo. Per assegnare un task al processore, però, c’è bisogno
di un’operazione di context switching, durante la quale il dispatcher si occupa di salvare lo
stato attuale del processo e ripristinare lo stato del task da mandare in esecuzione e salvato
in precedenza, operazione che in realtà avviene in qualsiasi altro sistema operativo. Tutte
queste informazioni utili al context switching e di conseguenza all’esecuzione di un task,
sono conservate nel cosiddetto Thread Control Block (TCB).
Di seguito è presente una disamina per ogni algoritmo di scheduling previsto dal sistema,
ponendo particolare attenzione soprattutto agli algoritmi di EDF e CBS, che risultano
leggermente più complessi per quanto riguarda il comportamento generale e il modo in cui
vengono implementati.
2.1 Deterministic Priority Scheduler (DPS)
DPS, come già specificato in fase d’introduzione, è l’unico algoritmo di scheduling
presente da sempre in RTEMS a partire dalla prima versione del sistema, ed è di tipo
preemptive, vale a dire ha la possibilità di interrompere temporaneamente un processo in
qualsiasi momento in favore di un altro a priorità più alta, per poi riattivarlo una volta che
il task prioritario ha terminato la sua esecuzione. L’implementazione di quest’algoritmo
prevede l’utilizzo di un array di code FIFO, ciascuna con una sua priorità; scelta la coda da
servire, i task saranno mandati in esecuzione con politica First In First Out, quindi il
primo processo ad essere servito sarà quello che è arrivato prima degli altri. Le code
presenti sono 256, una per ogni livello di priorità, in questo modo l’algoritmo in questione
costa solo tre Kilobytes di memoria RAM al sistema, un utilizzo davvero esiguo in termini
13
di risorse hardware. Per utilizzare questo scheduling la direttiva di pre-compilazione da
inserire
nel
codice
sorgente
del
programma
sviluppato
è
CONFIGURE_SCHEDULER_PRIORITY e fa uso di un solo core, quindi non è
perfettamente ottimizzato per sistemi multiprocessore.
2.2 Simple Priority Scheduler (SPS)
Il funzionamento di SPS è molto simile a DPS, anzi a dire il vero il modo in cui agisce è
perfettamente identico, cambia però l’implementazione reale dell’algoritmo. Questa volta
a essere utilizzata è una singola struttura dati, una lista linkata utile a gestire tutti i task
nella coda dei processi pronti, tutto ciò però a discapito della complessità: la struttura
dell’implementazione prevede, infatti, che venga eseguita una ricerca lineare sui task
ready per decidere quale mandare in esecuzione, chiaramente in base alle priorità
assegnate. Facendo un veloce confronto con DPS, il Simple Priority Scheduler è ancor più
parsimonioso in termini di risorse utilizzate, tuttavia prevede una maggiore complessità
nell’algoritmo di selezione dei task calcolata come O(n), con n numero di task pronti,
dovuta alla già citata ricerca lineare. Possiamo concludere dicendo che SPS è una buona
soluzione da adottare in RTEMS solo se viene utilizzato in piccoli sistemi con un numero
di task da gestire abbastanza esiguo, in questo caso la complessità è trascurabile ma
abbiamo un buon guadagno in termini di impiego delle risorse. Nel caso in cui si voglia
utilizzare questo scheduling, la direttiva di pre-compilazione da specificare è
CONFIGURE_SCHEDULER_SIMPLE, anche in questo caso l’algoritmo non è
ottimizzato per sistemi multi-core.
2.3 Simple SMP Priority Schedule (SSMP)
Parlando di DPS e SPS, abbiamo già sottolineato che si tratta di due soluzioni utilizzabili
in sistemi single core, mentre per quanto riguarda le architetture multiprocessore risultano
decisamente poco efficienti. SSMP non è altro che l’adattamento di Simple Priority
Scheduler a sistemi dotati di più core della CPU che lavorano nello stesso momento. La
particolarità di quest’algoritmo consiste nel riuscire a schedulare threads differenti tra i
14
diversi core di un’architettura symmetric multiprocessor (SMP), inoltre fornisce anche una
soluzione nel momento in cui bisogna prelazionare uno fra diversi threads aventi la stessa
priorità: l’algoritmo in questo caso non fa altro che sospendere il thread che ha eseguito
per più tempo tra quelli prelazionabili. Per quanto riguarda quest’algoritmo, la direttiva
pre-compilativa da specificare è CONFIGURE_SCHEDULER_SIMPLE_SMP.
2.4 Earliest Deadline First (EDF)
Un algoritmo di scheduling alternativo a DPS e SPS, per quanto riguarda le applicazioni
single core, è il famoso EDF. Così come suggerisce l’acronimo, Earliest Deadline First
manda in esecuzione tra i processi pronti quello con la deadline più vicina, o per meglio
dire deadline assoluta più breve, in maniera tale da unificare il concetto di priorità e
deadline stesso, seppur in maniera inversamente proporzionale. Le deadline vengono
calcolate a loro volta con il Rate Monotonic manager, di cui si è già parlato nel capitolo
precedente, che le fa coincidere con il periodo dei task, dopodiché tutti i processi sono
inseriti all’interno di un’unica coda ready implementata come un albero Red-Black.
Bisogna tuttavia porre l’accento su un aspetto fondamentale di EDF utilizzato in RTEMS,
i task all’interno del sistema hanno due tipi di priorità differenti, descrivibili in questo
modo: se un processo ha una deadline che è stata fissata utilizzando il Rate Monotonic
Manager allora la deadline stessa coincide con la priorità e il task è detto priority-driven;
nel caso in cui invece il task non ha una deadline specificata, oppure quella
precedentemente fissata è stata cancellata, allora viene definito processo di background, e
la priorità è quella assegnata durante l’inizializzazione. A questo punto per quanto
riguarda la schedulazione vera e propria, vengono mandati in esecuzione dapprima tutti i
task priority-driven, dopodiché si passa a quelli di background in base alle priorità iniziali.
Si intuisce quindi che a causa dell’utilizzo dell’algoritmo EDF con l’esecuzione di task
periodici, il Rate Monotonic Manager è di importanza fondamentale, per questo motivo
vengono messe a disposizione alcune direttive come rtems_rate_monotonic_period per
dichiarare
le
varie
deadline,
oltre
a
rtems_rate_monotonic_cancel
e
rtems_rate_monotonic_delete per cancellare la deadline precedentemente assegnata ad un
15
task. Non bisogna dimenticare, infine, che tra i vantaggi offerti da EDF uno dei più
importanti è quello di sfruttare un’altissima quantità di CPU, teoricamente il 100%, con
una complessità dell’algoritmo pari a O(log(n)) dovuta alla ricerca all’interno dell’albero
Red-Black, dove n è il numero di task presenti nella coda ready del sistema. Anche in
questo caso nel codice sorgente dell’applicazione bisogna dichiarare l’utilizzo di EDF,
attraverso la direttiva CONFIGURE_SCHEDULER_EDF.
2.5 Constant Bandwidth Server Scheduler (CBS)
CBS è un’estensione di EDF, o meglio la differenza tra i due algoritmi è la presenza di un
Server in CBS particolarmente utile soprattutto quando abbiamo la presenza
contemporanea nel sistema di task periodici e aperiodici: il problema cardine è garantire
l’esecuzione dei task periodici (di tipo hard real-time) senza ritardare eccessivamente
quelli aperiodici. Tra le sue caratteristiche principali c’è di sicuro quella di assicurare un
isolamento temporale dei task: in parole povere le esecuzioni dei vari processi non si
influenzano a vicenda, ma viceversa si comportano come se ogni task avesse a
disposizione un processore dedicato e indipendente dagli altri. Il Constant Bandwidth
Server prevede anche un meccanismo di protezione utile ad assicurare che la banda
allocata al server non sia superata, indipendentemente dalle richieste di calcolo dei task.
Analizzando il modo in cui viene implementato il tutto in maniera pratica, è chiaro che
ciascun task è assegnato ad un server, caratterizzato da un periodo e una capacità che
indica il massimo budget consumabile all’interno del periodo stesso, mentre la banda del
server non è altro che il rapporto tra questi due valori (capacità/periodo): concretamente
essa può essere definita come la frazione di CPU riservata dallo scheduler per ogni
periodo successivo; definito Ts il periodo e Qs il budget, la banda allocata al server sarà
Us = Qs / Ts. Oltre a questi fattori, in ogni istante lo stato del server può essere
rappresentato con altri due valori:
-
Cs: budget o capacità del server all’istante t, inizialmente è uguale 0 ma può assumere al
massimo un valore pari a Qs.
16
-
Ds: deadline corrente assegnata a un task, anch’essa inizialmente è 0, può essere spostata di
un particolare valore e in corrispondenza di particolari eventi come descritto in seguito.
Tenendo ben presenti i fattori e simboli fino ad ora descritti, a questo punto è possibile
analizzare le regole alla base del funzionamento di CBS, sintetizzabili in quattro punti
fondamentali, ciascuna per ogni condizione di funzionamento:
1. Se arriva una nuova richiesta quando quella attuale è attiva, la nuova viene inserita
all’interno di una coda gestita tipicamente con politica FIFO (First In First Out).
2. Ipotizzando l’arrivo di una nuova richiesta all’istante t, nel momento in cui il server
è idle (nessuna richiesta in esecuzione) possiamo avere due condizioni con le
relative conseguenze, valutando la disuguaglianza 0 < Cs ≤ (Ds - t)*Us: se Cs (il
budget attuale del server) è compreso tra quei due valori, allora la richiesta viene
servita con i valori attuali del server, altrimenti se la disuguaglianza non è
soddisfatta, si pone Cs = Qs (budget attuale uguale alla capacità originaria) e Ds =
t + Ts (la deadline della richiesta viene traslata di una quantità pari al periodo del
server).
3. Quando la richiesta corrente viene completata, il server si occupa di quella
successiva, qualora fosse presente all’interno della coda, utilizzando eventualmente
i valori attuali.
4. Quando invece il budget del server si annulla (Cs = 0) viene riportato nuovamente al
valore massimo, vale a dire Qs, mentre la deadline viene ritardata di un periodo Ds
= Ds + Ts.
Quest’ultima regola è in realtà un meccanismo di protezione temporale che rende il tutto
molto affidabile, ma è causa di prestazioni non proprio elevatissime di CBS rispetto ad
17
altri algoritmi di scheduling.
Constant Bandwidth Server, inoltre, offre delle proprie API che permettono alle
applicazioni di fissare la deadline in maniera diretta, senza l’utilizzo della direttiva
rtems_rate_monotonic_period e di conseguenza del Rate Monotonic Manager, come
avviene invece per EDF. Tra le altre direttive più importanti utilizzabili troviamo
rtems_cbs_initialize per l’inizializzazione del server, rtems_cbs_set_parameters per
impostare i parametri, rtems_cbs_get_server_id per ottenere l’id del server in uso e molte
altre. In fase di pre-compilazione del codice sorgente dell’applicazione, invece, la direttiva
da usare è CONFIGURE_SCHEDULER_CBS.
18
Capitolo 3: Ciclo di vita dei task
Un task in RTEMS durante la schedulazione può trovarsi in cinque stati differenti, in base
alle condizioni durante il suo ciclo di vita: executing, ready, blocked (o waiting), dormant
e non-existent (o terminated). La struttura e il collegamento tra i vari stati sono ben visibili
all’interno del grafo in figura 2, tuttavia è importante andare ad analizzare ciascuno stato o
transizione e le condizioni sotto le quali avvengono cambiamenti. Un task è nello stato
non-existent fino a quando è richiamata la direttiva rtems_task_create, mentre subisce una
transizione da qualsiasi altro stato a quello di non-existent con la chiamata della direttiva
rtems_task_delete. Un task presente in questo stato non ha un ID o un TCB assegnato e da
qui deriva la sua denominazione, giacché il task in questione è come se non esistesse per
gli altri processi del sistema, in pratica non può essere richiamato in alcun modo. Quando
un task si trova nello stato di non-existent e viene richiamata la direttiva create, una
transizione lo fa arrivare nello stato dormant dove di fatto risulta dormiente ma non ancora
attivo, di conseguenza non potendo utilizzare risorse di sistema permane in questa
condizione fino a quando viene richiamata la direttiva rtems_task_start, a quel punto lo
troveremo nella coda dei processi pronti dove potrà essere schedulato dal processore e
grazie al dispatching entrare nello stato di executing. Durante la sua esecuzione un task
può bloccarsi poiché ad esempio è in attesa di un mutex, oppure può essere bloccato da un
altro task presente nel sistema sotto dovute condizioni: nel primo caso il processo ha la
facoltà di utilizzare alcune direttive come ad esempio rtems_task_wake_after o
rtems_task_wake_when, nel secondo caso invece l’unica direttiva utilizzabile è
rtems_task_suspend; nel prossimo paragrafo verranno descritte in maniera più precisa tutte
le condizioni verificabili e le loro conseguenze nella transizione che porta un task a
19
bloccarsi o a tornare nella coda dei processi pronti.
Figura 2: Grafo delle transizioni
Per quanto riguarda invece la modalità di esecuzione vera e propria di un processo in
RTEMS, essa può essere espressa con quattro elementi fondamentali o campi:
•
Preemption: indica la possibilità di un task di essere prelazionato o meno.
•
Timeslicing: è utilizzato per l’assegnazione della CPU a diversi processi aventi la stessa
priorità. Più precisamente se il campo suddetto è abilitato, il sistema va a limitare il tempo
massimo di esecuzione di un task prima ancora che un altro task di eguale priorità venga
schedulato dalla CPU, regolando le operazioni di context switching dei task ugualmente
prioritari.
•
ASP: acronimo di Asynchronous Signal Processing, se è abilitato, indica che i segnali
ricevuti dal task saranno gestiti durante la prossima esecuzione del processo stesso.
Viceversa, se l’opzione è disabilitata i segnali ricevuti rimangono in attesa fino a quando
ASP non viene riabilitato.
•
Interrupt: il campo seguente indica invece quale livello delle interruzioni è abilitato durante
l’esecuzione del task, ricordando che RTEMS supporta 256 livelli diversi di interrupt.
20
Queste componenti vengono usate, quindi, per modificare il processo di scheduling e
alterare l’esecuzione di un task, il tipo di dato utilizzato per gestire la modalità di
esecuzione dei task è rtems_task_mode.
Riprendendo invece la disamina fatta per le caratteristiche di ciascun task, ognuno di essi
può avere degli attributi, descrivibili in questo modo:
•
RTEMS_NO_FLOATING_POINT: il processo non usa il coprocessore numerico.
•
RTEMS_FLOATING_POINT: il processo utilizza il coprocessore numerico (occupa
maggiore memoria).
•
RTEMS_LOCAL: c’è un’area privata per variabili non condivisibili con altri task (occupa
maggiore memoria).
•
RTEMS_GLOBAL: le variabili utilizzate dal task sono globali.
Il fatto che i task local e floating point occupino maggiore memoria, è dovuto alla
necessità di memorizzare informazioni riguardo lo stato delle variabili di tipo privato o
della floating point unit.
Infine per terminare il discorso riguardo la gestione dei task in RTEMS e il relativo ciclo
di vita con le transizioni corrispondenti, è necessario dare uno sguardo alle primitive
utilizzabili, tutto ciò nell’approfondimento che segue dove, come già descritto in
precedenza, ci si soffermerà sullo blocco e sblocco dei task.
3.1 Condizioni di blocco/sblocco di un task
Durante il capitolo seguente sono state prese in considerazione le varie transizioni che
portano un task a passare da uno stato all’altro, ora l’attenzione sarà posta sulle condizioni
che devono essere verificate affinché un processo passi dallo stato blocked a quello ready
e viceversa, considerando anche i passaggi da e verso lo stato di executing.
21
Un task qualsiasi può entrare nello stato di blocking se è verificata una di queste sette
condizioni, ciascuna associata a una direttiva utilizzata, alcune delle quali già nominate in
precedenza:
•
Un task richiama la direttiva rtems_task_suspend che blocca esso stesso o un altro processo
del sistema;
•
Il task in esecuzione richiama la direttiva rtems_message_queue_receive con la condizione
d’attesa e la coda dei messaggi vuota.
•
Il processo che sta eseguendo richiama la direttiva rtems_task_wake_after, con la quale si
blocca per un certo periodo di tempo specificato durante la chiamata stessa. Se il campo
corrispondente all’intervallo da definire è zero, il task torna subito nello stato ready.
•
Utilizzando la direttiva rtems_task_wake_when, il processo si blocca fino a quando non
viene raggiunto l’istante di tempo indicato, in corrispondenza del quale il task viene
risvegliato come vedremo nelle condizioni di sblocco.
•
Un processo può richiamare la direttiva rtems_region_get_segment con una condizione
d’attesa, poiché non c’è un segmento di memoria abbastanza ampio da soddisfare la
richiesta del task.
•
Un task in esecuzione con la direttiva rtems_semaphore_obtain si blocca con una
condizione di wait e il semaforo voluto non disponibile.
•
Il processo in esecuzione con la direttiva rtems_event_receive si blocca sempre con una
condizione di attesa, poiché in questo caso gli eventi in corso in quel momento nel sistema
non soddisfano la richiesta.
•
La direttiva rtems_rate_monotonic_period indica che il task corrente deve attendere uno
specifico periodo rate monotonic per terminare l’esecuzione.
Un processo in RTEMS, d’altro canto, può rientrare nello stato ready se è verificata una di
queste altre sette condizioni differenti, ancora una volta associate a direttive:
•
Un task in esecuzione può richiamare rtems_task_resume con la quale riattivare un processo
22
sospeso che non è in attesa di alcuna risorsa dal sistema.
•
Un task mentre esegue può richiamare le direttive rtems_message_queue_send,
rtems_message_queue_broadcast o rtems_message_queue_urgent che inseriscono un
messaggio nella coda sulla quale il processo bloccato è in attesa, in maniera tale da farlo
tornare nello stato di ready, pronto per essere schedulato.
•
Un processo con la direttiva rtems_semaphore_release può, invece, rilasciare un semaforo
sul quale c’è un task bloccato in attesa.
•
Attraverso la direttiva rtems_event_send, un task può inviare una “event_condition” ad un
altro processo bloccato in attesa di quella stessa condition.
•
Un processo può sbloccarsi se è terminato l’intervallo di tempo specificato nella direttiva
rtems_task_wak_after utilizzata per eseguire la transizione verso lo stato di blocked.
•
Un task che ha in precedenza richiamato la direttiva rtems_task_wake_when, viene
sbloccato e torna nello stato di ready se arriva quell’istante specificato nella direttiva.
•
Un task richiama la direttiva rtems_region_return_segment quando il segmento di memoria
sul quale era bloccato il processo diventa disponibile ed è abbastanza ampio da contenerlo.
•
Dopo aver utilizzato la direttiva rtems_rate_monotonic_period per la transizione nello stato
di blocked, un task torna nella coda dei processi pronti quando vede terminare il periodo
specificato nella direttiva stessa.
•
Un processo nello stato blocked può sbloccarsi anche utilizzando semplicemente
rtems_task_restart in maniera diretta.
•
Se un intervallo di timeout termina con un task che era bloccato su un evento particolare, un
messaggio, un segmento o un semaforo, torna ad essere ready e si sblocca.
•
Se un altro processo utilizza una direttiva per eliminare una coda di messaggi, un semaforo
o una regione di memoria su cui era bloccato un altro task, quel task torna nella coda dei
processi ready.
23
Capitolo 4: RTEMS in ambiti applicativi
Così come specificato durante l’introduzione, il sistema operativo RTEMS è stato ed è
attualmente utilizzato in numerosi domini applicativi, l’ambito che spicca maggiormente
sotto questo punto di vista è di sicuro quello spaziale, di cui fanno parte i due progetti
descritti nei paragrafi seguenti. Come detto, però, le applicazioni pratiche di questo
sistema sono davvero tante, troviamo progetti in ambito militare, industriale, di ricerca
scientifica e persino progetti in campo sportivo, come la famosa BMW S1000R che
partecipa ancora oggi al mondiale Superbike ed è stata guidata negli anni scorsi anche dal
connazionale Marco Melandri: la moto in questione utilizza RTEMS per loggare i dati
dell’engine control unit, più precisamente è presente un logger in esecuzione su RTEMS
che va a collezionare una serie di dati a una velocità di 2 MB/s per l’analisi delle
performance del veicolo, dopodiché il data logger usa il sistema per ottenere un
comportamento ottimale e con un’alta percentuale di affidabilità nell’operazione di
memorizzazione dei dati, i quali saranno ovviamente di fondamentale importanza per lo
sviluppo e il miglioramento delle performance del veicolo.
4.1 Solar Dynamic Observatory (SDO)
Il Solar Dynamic Observatory è un telescopio spaziale lanciato con successo dalla NASA
l’11 febbraio 2010 per studiare il Sole, progettato per restare in orbita cinque anni, ha
come obiettivo principale quello di investigare sull’influenza dell’attività solare sulla terra.
In realtà SDO fa parte di un programma più ampio chiamato “NASA’s living with a star”
(LWS), di cui è stato il primo progetto messo in atto. Analizzando gli obiettivi principali
di questa sonda in maniera più approfondita, scopriamo che il progetto ha due finalità
24
fondamentali: studiare come viene generato e com’è strutturato il campo magnetico solare,
e capire in che modo quest’energia magnetica viene convertita e rilasciata nello spazio
sotto forma di vento solare e particelle energetiche. I sistemi real-time in generale vengono
molto utilizzati in applicazioni di questo tipo, in quanto c’è la necessità di catturare una
serie di informazioni ed elaborarle in un tempo prefissato, in questo caso si è scelto di
utilizzare RTEMS per gestire le operazioni di I/O della sonda: il satellite dispone, infatti,
di cinque processori chiamati radiation hardened coldfire CPU, sui quali gira il sistema
operativo trattato all’interno di questo elaborato; abbiamo a disposizione quindi delle CPU
Coldfire, derivate dalla famiglia del famoso Motorola 68000 e utilizzate soprattutto in
sistemi embedded, in questo caso però sono state opportunamente modificate per essere
hardened, vale a dire con lo scopo di minimizzare l’impatto di possibili vulnerabilità,
migliorando di fatto la sicurezza complessiva. RTEMS, quindi, risulta particolarmente
utile soprattutto per gestire le operazioni di I/O, di conseguenza si occupa di elaborare e
sincronizzare i dati derivanti dai vari sensori e strumenti della sonda, il tutto con
l’affidabilità assicurata dall’utilizzo di un sistema real-time; in maniera più specifica, la
strumentazione scientifica del satellite è costituita da tre elementi fondamentali:
• Uno strumento chiamato Extreme Ultraviolet Variability Experiment che misura
l’emissione di radiazione ultravioletta con cadenza regolare e con un alto tasso di
precisione, ed è proprio da qui che nasce l’esigenza di avere processi che
terminano la loro esecuzione in un determinato intervallo di tempo.
• Un altro strumento chiamato Atmospheric Imaging Assembly si occupa invece di
fornire un’immagine piuttosto dettagliata del disco solare nelle differenti bande
dell’ultravioletto.
• L’Helioseismic and Magnetic Imager è l’ultimo elemento di particolare importanza
della sonda che studia la variabilità dell’attività solare e le sue componenti
magnetiche.
Questi tre elementi collaborano tra loro scambiando e memorizzando informazioni in
maniera affidabile e precisa grazie al sistema operativo RTEMS.
25
4.2 Electra
Un altro progetto particolarmente rilevante che fa uso di RTEMS è senz’altro Electra, un
SDR (Software Defined Radio) che, in linea con gli altri software appartenenti a questa
categoria, permette di costruire dei ricevitori radio lavorando quasi completamente a livello
software e non più hardware, con un supporto multistandard poiché chiaramente il software
è riprogrammabile e particolarmente flessibile. Electra è stato sviluppato dal “Jet
Propulsion Laboratory” situato a Pasadena (California), ed è diventato il sistema software
al centro delle missioni spaziali su Marte dall’Agosto del 2005 grazie al Mars
Reconnaissance Orbiter (MRO). Questi software sono in grado di inoltrare i dati ed
eseguire misurazioni di alta precisione radiometrica, Electra, infatti, è una parte
fondamentale dell’infrastruttura per i dispositivi di questo tipo, in quanto permette di
trasmettere comandi dalla terra alla superficie di Marte e di restituire dati scientifici ed
ingegneristici attraverso gli MRO. Entrando più nello specifico per quanto riguarda
l’architettura di Electra, si dispone in linea generale di un processore Sparc V-7 25 Mhz e
alcuni Megabyte di memoria centrale, quindi si ha a disposizione una dotazione hardware
piuttosto modesta, ma che, di fatto, permette di avere abbastanza potenza computazionale e
memoria a sufficienza per ospitare un filtro di navigazione real-time: è proprio grazie ai
bassi requisiti richiesti da RTEMS, in termini di RAM e CPU, che questo sistema operativo
risulta un’ottima base software per Electra, come se non bastasse le funzionalità messe a
disposizione da questo SDR vanno ben oltre quelle che sono le reali capacità dell’hardware
a disposizione, tutto ciò grazie al sistema operativo real-time utilizzato; a questo proposito
utilizzando queste caratteristiche di Electra e RTEMS molto parsimoniose in termini di
risorse, è stato possibile utilizzare le altre risorse hardware per scopi differenti, come ad
esempio il fatto che numerosi dati radiometrici dopo essere stati elaborati vengano resi
disponibili localmente in Electra, anziché essere trasferiti sul Bus dati. Tra i primi progetti
che hanno fatto uso di Electra c’è stato di sicuro Phoenix, un lander stazionario che ha
permesso di studiare il polo nord di Marte nel 2008, raccogliendo dei dati che saranno di
importanza fondamentale per individuare le zone utili da esplorare durante le prossime
missioni su questo pianeta del sistema solare.
26
Conclusioni
Durante l’elaborato sono stati presi in considerazione alcuni aspetti fondamentali per il
funzionamento di RTEMS, ma anche per qualsiasi altro sistema operativo Real Time,
come lo scheduling e il ciclo di vita dei task. Ovviamente tutto ciò che abbiamo detto fino
ad ora, per essere utilizzato, deve essere messo in pratica attraverso un’operazione di
Building, termine che indica la compilazione e il deployment del sistema operativo sulla
board di destinazione. Tutto ciò prevede l’utilizzo di una workstation per la crosscompilazione del codice da eseguire, che può essere sia di tipo Linux che Windows grazie
a dei tool messi a disposizione dall’azienda, un Debugger per il download e il
monitoraggio del file eseguibile, e infine la board dove dovrà essere eseguito il sistema
operativo per quella particolare applicazione, eventualmente emulata per eseguire
particolari prove prima della messa in pratica del progetto. Da qui si capisce come sia
estremamente semplice compiere piccoli test di progetti anche piuttosto complessi che
utilizzano RTEMS, ed è proprio questa semplicità e apertura del codice, di cui abbiamo
parlato durante l’introduzione, unita alle esigue risorse hardware richieste dal sistema, che
fanno di RTEMS uno dei sistemi operativi real-time maggiormente utilizzato sia per
progetti indipendenti che finanziati e di particolare importanza o criticità, così come
abbiamo potuto scorgere nel corso dell’ultimo capitolo.
27
Bibliografia
[1]
RTEMS Real Time Operating System (RTOS), http://rtems.org, 26 Aprile 2014
[2]
G.Buttazzo, Sistemi in Tempo Reale, Pitagora Editrice, 404.
[3]
NASA – Mars Exploration Program, http://mars.jpl.nasa.gov, 26 Aprile 2014
28