valutazione mediante fault injection di sistemi operativi

152
Facoltà di Ingegneria Corso di Studi in Ingegneria Informatica tesi di laurea specialistica Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo Anno Accademico 2008/2009 relatore Ch.mo prof. Domenico Cotroneo relatore Ing. Marcello Cinque candidato Ciro Manfellotto matr. 885/101

Upload: others

Post on 26-Nov-2021

2 views

Category:

Documents


0 download

TRANSCRIPT

Facoltà di Ingegneria Corso di Studi in Ingegneria Informatica

tesi di laurea specialistica

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo Anno Accademico 2008/2009 relatore Ch.mo prof. Domenico Cotroneo relatore Ing. Marcello Cinque candidato Ciro Manfellotto matr. 885/101

I

Ai miei genitori

II

Indice Introduzione 1 Capitolo 1. Le Wireless Sensor Networks 4 1.1 Le WSN 4 1.2 Parametri di progetto per una WSN 6 1.3 Applicazioni delle WSN 7 1.4 Architettura di un nodo sensore 9 1.4.1 Sensing module 10 1.4.2 Unità di elaborazione 11 1.4.3 Unità di comunicazione 11 1.4.4 Alimentazione 12 1.5 Sistemi operativi per WSN 12 1.5.1 Il sistema operativo TinyOS 13 1.5.1.1 Architettura di TinyOS 15 1.5.1.2 Componenti in TinyOS 17 1.5.1.3 Il frame 18 1.5.1.4 I comandi 18 1.5.1.5 Gli eventi 19 1.5.1.6 I task 19 1.5.1.7 Lo scheduler 20 1.5.1.8 Operazioni split-phase 21 1.5.1.9 Active Messages 21 1.5.2 Il sistema operativo Mantis OS 22 1.5.2.1 Architettura di Mantis OS 23 1.5.2.2 Kernel e scheduler 24 1.5.2.3 Stack protocollare 25 1.5.2.4 Riprogrammazione dinamica 26 1.6 La dependability delle WSN 27 1.7 Guasti, errori e malfunzionamenti 28 1.7.1 Faults nel nodo sensore 29 1.8 Valutazione della dependability 30

III

Capitolo 2. Fault injection 32 2.1 Tecniche di fault injection 33 2.1.1 Harware-Implemented fault injection 33 2.1.2 Software-Implemented fault injection 34 2.1.3 Fault injection a tempo di compilazione e a tempo di esecuzione 35 2.1.4 Fault injection a livello assembly 37 2.2 Descrizione della tecnica SWIFI utilizzata e modifiche apportate 37 2.2.1 Descrizione della tecnica di injection 37 2.2.2 Guasti 39 2.2.3 Guasti in memoria dati 39 2.2.4 Guasti nel codice 40 2.2.5 Guasti nei registri del processore 41 2.2.6 Tecnica per la rilevazione dell’istante di injection 41 2.2.7 Modifiche apportate 44 Capitolo 3. AVR-INJECT Tool versione 2.0: la progettazione 51 3.1 AVR-INJECT Tool 51 3.2 Casi d’uso del tool 53 3.3 Component diagram 57 3.4 Class diagram 59 3.5 Sequence diagram 65 3.5.1 Sequence diagram n°1: nuovo esperimento 65 3.5.2 Sequence diagram n°2: esecuzione di un prog etto 67 3.6 Problematiche affrontate 69 Capitolo 4. AVR-INJECT Tool: esecuzione di un progetto 75 4.1 Creazione e configurazione di un progetto 75 4.2 Configurazione di uno studio step-by-step 78 4.3 Esecuzione di un progetto e visualizzazione dei risultati 83 4.4 Files generati dal tool 85 4.4.1 File Esp_*.od 86 4.4.2 File esp_avrora.txt 87 4.4.3 File esp_Memory.txt 87 4.4.4 Files esp_Profile.txt e esp_Calls.txt 87 4.4.5 File Trace.txt 88 4.4.6 File avr.sh 88 4.4.7 File avrGrep.sh 88 4.4.8 File Risultati.txt 89 Capitolo 5. Utilizzo del tool: analisi comparativa tra TinyOS e Mantis 90 5.1 Fault injection in Mantis OS 92 5.1.1 Code Error Injection 93 5.1.2 Memory Error Injection 97

IV

5.1.3 PC Error Injection 101 5.1.4 SP Error Injection 103 5.1.5 SR Error Injection 107 5.1.6 Mantis Total Error Injection 110 5.2 Fault injection in TinyOS 113 5.2.1 Code Error Injection 113 5.2.2 Memory Error Injection 117 5.2.3 PC Error Injection 121 5.2.4 SP Error Injection 124 5.2.5 SR Error Injection 127 5.2.6 TinyOS Total Error Injection 131 5.3 Risultati ottenuti con l’applicazione surge 133 5.3.1 Risultati totali in Mantis OS 134 5.3.2 Risultati totali in TinyOS 136 5.4 TinyOS vs Mantis OS 139 Conclusioni 143 Sviluppi futuri 144 Bibliografia 145 Sitografia 147

1

Introduzione

Gli sviluppi tecnologici, avvenuti negli ultimi anni nel campo dell’elettronica e

dell’informatica, hanno reso possibile lo sviluppo di reti di sensori senza filo (dette anche

WSN che è l’acronimo di Wireless Sensor Networks). In virtù delle loro caratteristiche,

esse possono essere utilizzate per una moltitudine di applicazioni nei campi più disparati:

tipiche applicazioni sono quelle per la rilevazione, il controllo, la comunicazione, la

sorveglianza e il monitoraggio sia in ambito militare che civile.

Le WSN possono anche essere utilizzate per applicazioni critiche, queste ultime si

differenziano dalle normali applicazioni per i requisiti di qualità ed affidabilità

estremamente stringenti. In questo caso è necessario garantire la dependability in quanto

un qualsiasi malfunzionamento potrebbe provocare gravi danni a persone e/o cose. Il

concetto di affidabilità esprime la capacità di una WSN di lasciare inalterate le proprie

funzionalità anche in caso di eventuali guasti di qualche nodo sensore oppure in seguito al

fallimento di una trasmissione (un pacchetto inviato non arriva a destinazione).

Il lavoro di tesi svolto può essere decomposto in due fasi: 1) modifica di un tool per

l’iniezione di guasti in microcontrollori per WSN; 2) utilizzo del tool per l’analisi

comparativa tra due sistemi operativi per WSN.

Il tool, realizzato in un precedente lavoro di tesi, utilizza una tecnica di iniezione a livello

assembly con inserzione di codice per iniettare guasti di tipo bit-flip di diversa natura

2

(Codice, Memoria, Program Counter e Status Register). Inoltre per il suo funzionamento è

utilizzato l’emulatore Avrora, che permette di emulare una rete di sensori senza filo i cui

nodi sono dei microcontrollori AVR.

Le modifiche apportate al tool durante la prima fase del lavoro di tesi comprendono:

l’ampliamento delle destinazioni dei guasti (aggiunta del registro Stack Pointer), la

correzione di alcuni problemi riscontrati e l’analisi automatica dei risultati che comprende

la classificazione degli errori riscontrati e la generazione dei relativi grafici.

Nella seconda fase del lavoro di tesi è stata svolta un’analisi comparativa tra due sistemi

operativi per reti di sensori senza filo: TinyOS e Mantis. In particolare, attraverso l’utilizzo

del tool, è stata realizzata una campagna di fault injection su due applicazioni simili (Blink

di TinyOS e blink_led di Mantis) allo scopo di valutare il comportamento dei due sistemi

operativi in presenza di guasti.

Il lavoro di tesi è strutturato in 5 capitoli; di seguito riportiamo una breve descrizione per

ogni capitolo.

Il capitolo 1 fornisce una panoramica delle WSN, in particolare si inizia con una

contestualizzazione necessaria a descrivere e valutare l’affidabilità nelle WSN. Si procede

poi con la descrizione di due sistemi operativi per WSN (TinyOS e Mantis) e si conclude

con l’introduzione del concetto di Fault Injection presentando a tal proposito le principali

problematiche della Fault Injection nelle WSN.

Il capitolo 2 descrive le principali tecniche di fault injection note, in particolare viene

analizzata in modo dettagliato la tecnica di iniezione utilizzata dal tool mettendo in

evidenza le modifiche apportate durante il lavoro di tesi.

Il capitolo 3 descrive la parte di progettazione della nuova versione del tool mettendo in

evidenza le novità introdotte, le modifiche apportate e le problematiche affrontate.

Vengono presentati e descritti, per gli scenari più significativi, alcuni casi d’uso per

illustrare il funzionamento del tool, il component diagram per evidenziare i componenti

principali che costituiscono l’applicazione, il class diagram ed alcuni sequence diagram.

3

Il capitolo 4 fornisce una descrizione dell’utilizzo del tool in cui si spiega come creare e

gestire un generico progetto dell’applicazione. Con l’ausilio di una sequenza di schermate,

che riportano i punti salienti dell’applicazione, è possibile capire come lavora il tool e

familiarizzare con l’interfaccia GUI che si presenta semplice e facile da usare per un

qualsiasi utente. Infine si descrivono brevemente i file generati da Avrora ed utilizzati per

l’analisi dei risultati.

Il capitolo 5 descrive la campagna di fault injection realizzata per l’analisi comparativa tra

TinyOS e Mantis, mettendo in evidenza gli obiettivi, le metriche utilizzate ed il piano degli

esperimenti. I risultati ottenuti sono mostrati in forma grafica utilizzando i grafici generati

dal tool.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

4

Capitolo 1

Le Wireless Sensor Networks

Il mondo delle reti di telecomunicazioni è in continua espansione, come testimonia la

capillare di diffusione delle reti ad estensione geografica (Wide Area Network). Da molti

anni si è intuito che il limite principale delle reti è costituito dalle infrastrutture necessarie

al loro funzionamento. Cavi e punti di accesso rappresentano un grosso ostacolo per

l’espansione della rete stessa, operazione che diventa alquanto costosa in termini di tempo

e risorse. Una valida soluzione in merito è rappresentata dall’utilizzo di reti ad hoc. Essa è

stata elaborata al preciso scopo di ottenere reti autoconfiguranti, che non necessitino di una

organizzazione gerarchica e soprattutto di infrastrutture. E’ indispensabile che reti di

questo tipo permettano di risolvere con efficacia problemi dovuti a guasti, spegnimenti e

mutamenti dell’ambiente operativo. Le reti di sensori senza filo, o Wireless Sensors

Networks(WSN) nascono alla stessa stregua delle reti ad hoc, focalizzandosi su

applicazioni di monitoraggio e controllo ambientale e strutturale.

Questo capitolo prima introduce al lettore le reti di sensori, focalizzando l’attenzione in

particolare sulle WSN (Wireless Sensor Networks) e poi descrive due tra i sistemi

operativi più utilizzati per questa tipologia di reti: TinyOS e Mantis.

1.1 Le WSN

Per comprendere cosa sia una rete di sensori definiamo innanzitutto un sistema distribuito.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

5

Un sistema distribuito è un sistema formato da un insieme di componenti dislocati su vari

calcolatori connessi tra loro attraverso una rete telematica e capaci di comunicare e

coordinare le loro azioni unicamente attraverso lo scambio di messaggi. Un sistema

distribuito è caratterizzato dalla concorrenza dei suoi componenti, dall’appartenenza a

diversi domini dei suoi componenti, da meccanismi di sincronizzazione e interazione basati

sullo scambio di messaggi, e dalla possibilità di guasti indipendenti dei suoi componenti.

Una rete di sensori è un sistema distribuito costituito da un insieme di nodi capaci di

ospitare sensori o attuatori, eseguire elaborazioni e comunicare tra loro attraverso

protocolli di rete multi-hop dove il messaggio giunge a destinazione dopo aver attraversato

un certo numero di nodi. Volendo dare una definizione un po’ più informale si può dire che

una Wireless Sensor Network è una rete costituita da un insieme di sensori distribuiti

nell’ambiente che cooperano tra di loro, mediante trasmissioni wireless (senza filo), allo

scopo di rilevare fenomeni fisici. Solitamente una WSN è costituita da una stazione base

(vedi figura 1.1) eventualmente connessa ad altre reti (mediante gateway) e da un certo

numero di sensori wireless (nodi). Il numero di sensori che costituiscono una rete può

variare da qualche decina a svariate migliaia di unità. Le informazioni raccolte vengono

poi inviate verso una stazione base, passando da un nodo all’altro secondo un protocollo

multi-hop ed infine trasferite, via internet o via satellite, verso un centro di raccolta.

Esistono configurazioni con più stazioni base mobili e i nodi inviano i loro dati verso un

sottoinsieme delle stazioni stesse.

Figura 1.1: Esempio di WSN

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

6

1.2 Parametri di progetto per una WSN

Per realizzare una buona WSN è necessario rispettare una metrica delle prestazioni. I

fattori che influiscono la progettazione delle reti di sensori senza filo sono vari, di seguito

descriviamo brevemente i fattori principali.

• Tolleranza ai guasti: è necessario innanzitutto garantire una tolleranza ai

guasti in quanto il mancato o errato funzionamento di alcuni nodi non deve

impedire lo svolgimento del task richiesto dall’utente.

• Topologia di rete: occorre saper scegliere un’opportuna topologia di rete in

base al luogo fisico in cui andrà posizionata la rete: i nodi possono avere una

disposizione di tipo mesh (a griglia), di tipo cluster (raccolti in sottoinsiemi)

oppure a stella (un nodo centrale di riferimento).

• Consumi: una WSN deve contenere i suoi consumi in quanto i nodi sono

provvisti di alimentazione autonoma (ad es. una batteria), tuttavia questa

alimentazione ha una durata limitata nel tempo quindi occorre anche saper

minimizzare il consumo dei dispositivi delle WSN. A tal proposito è lecito

ricordare che un dispendio energetico non trascurabile può essere dovuto ad

un malfunzionamento in una WSN: infatti in questo caso la rete deve

provvedere al reinstradamento dei pacchetti e all’individuazione di una nuova

topologia di rete.

• Scalabilità: una WSN deve essere scalabile cioè deve essere in grado di

lavorare con un numero di nodi elevato e consentire una semplice

aggregazione di nuovi nodi. Una rete di sensori senza filo può essere popolata

da decine o migliaia di nodi conservando in entrambi i casi una propria

stabilità e robustezza.

• Mezzi trasmissivi: la realizzazione di una discreta WSN è legata alla scelta

del mezzo trasmissivo da adottare. Dal momento che si tratta di una

comunicazione wireless (senza filo) tra i sensori, allora si possono usare gli

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

7

ultrasuoni, i raggi infrarossi oppure i segnali radio; nell’ultimo caso però

occorre tenere conto di particolari fenomeni fisici legati al mezzo trasmissivo

quali la riflessione, l’attenuazione o i cammini multipli dei segnali propagati.

• Prestazioni: misurare le prestazioni di una WSN significa valutare il suo

transfer rate (la velocità di trasferimento dei pacchetti tra i sensori), la sua

latenza (il tempo che intercorre tra la richiesta di inoltro di un pacchetto e

l’inizio dell’effettiva trasmissione del pacchetto) ed infine il Packet Error Rate

(la percentuale di generazione di pacchetti errati in un intervallo di tempo).

• Costo: dal momento che una rete di sensori senza filo può contenere fino a

migliaia di nodi, è bene valutare il giusto costo da investire. Occorre saper

scegliere il giusto rapporto qualità-prezzo e pertanto si cerca di spendere il

minimo per avere un prodotto efficiente ed efficace.

1.3 Applicazioni delle WSN

Le reti di sensori senza filo possono essere utilizzate nella realtà in diversi contesti che

spaziano dal controllo ambientale all’automazione casalinga, dalle applicazioni

commerciali ai servizi fino ad arrivare al settore sanitario. E’ possibile inoltre misurare una

vasta gamma di grandezze fisiche come l’umidità, la pressione, la temperatura, il suono,

l’intensità luminosa, le dimensioni di un oggetto, la presenza di oggetti in movimento e

anche la loro accelerazione. I sensori, grazie alle loro ridotte dimensioni, si adattano bene

ad ambienti ostili e inaccessibili (ad esempio in un bosco di una riserva naturale). Inoltre

grazie al loro elevato numero, risulta particolarmente facile monitorare grandezze in aree

relativamente ampie.

Nel controllo ambientale le WSN acquisiscono un ruolo fondamentale per seguire gli

spostamenti degli animali, ad esempio specie di animali protette, e per monitorare

determinate colture. Nel settore ambientale il principale ruolo ricoperto dalle reti di sensori

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

8

senza filo è costituito dalla segnalazione di incendi boschivi (numerosi soprattutto nel

periodo estivo) e quindi alla tempestività di inoltro del segnale d’allarme (ad esempio ad

un comando della guardia forestale o dei vigili del fuoco più vicino rispetto al luogo

dell’incendio).

Nel campo sanitario possiamo incontrare alcune applicazioni che usufruiscono delle WSN

per la realizzazione di interfacce per disabili oppure per il monitoraggio integrato dei

pazienti o in alcuni casi anche per il tele monitoraggio dei dati fisici di un individuo. Le

WSN vengono utilizzate anche per il monitoraggio del personale medico. In particolar

modo nelle applicazioni mediche esse vengono sfruttate per controllare determinati

parametri di un paziente quali la pressione sanguigna, la temperatura, le pulsazioni

cardiache, consentendo, qualora si riscontrasse un valore anomalo, la segnalazione e la

tempestività del soccorso da parte del personale medico. Quindi già da questi brevi esempi

è possibile immaginare quanto sia importante assicurarsi che un sensore sia tollerante ad

eventuali guasti che potrebbero generarsi, affinché non si verifichino conseguenze gravi

nella vita reale.

Nella Home automation si può pensare di avere una serie di elettrodomestici (forni a

microonde, frigoriferi, videoregistratori, lettori DVD etc). Questi possono interagire tra

loro e con una rete esterna, via internet o via satellite e consentono all’utente di comandare

facilmente gli elettrodomestici a distanza. In tal caso dunque le WSN vengono utilizzate in

ambienti intelligenti e non solo in casa ma anche negli uffici.

Nelle applicazioni commerciali si può pensare ad un ambiente lavorativo come ad un

ufficio nel quale viene erogata aria condizionata. Il monitoraggio dell’aria all’interno degli

uffici può essere eseguito proprio con una rete di sensori senza filo. Il flusso di aria

condizionata è controllato in maniera centralizzata; l’uso razionale dei sensori favorisce

una riduzione del loro consumo di energia.

Le reti di sensori wireless possono anche assumere un ruolo dominante nelle più comuni

attività militari come il comando, il controllo dei campi di battaglia, la rilevazione degli

spostamenti delle truppe nemiche, la sorveglianza e le operazioni di localizzazione dei

bersagli.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

9

Nel campo industriale le WSN possono essere utili per la guida e il controllo di robot nei

processi industriali oppure per la verifica delle categorie e della qualità di vari articoli

presenti in un grande magazzino.

Infine le reti di sensori senza filo si rivelano convenienti anche nel controllo del traffico di

autoveicoli (si pensi ad un tratto stradale critico).

La figura 1.2 illustra gli scenari di utilizzo delle WSN appena descritti.

1.4 Architettura di un nodo sensore

Una rete di sensori rappresenta un insieme di nodi sensore che formano una prestabilita

topologia. I nodi sono disposti all’interno di un’area in cui si osserva il fenomeno che si

vuole analizzare. Il numero di sensori che compongono una rete può variare da qualche

decina a svariate migliaia. Le informazioni raccolte vengono inviate ad una stazione base

(detta sink ), passando da un nodo all’altro secondo un protocollo multi-hop, ed infine

Figura 1.2: Scenari di utilizzo delle WSN

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

10

trasferite ad un centro di raccolta. Il nodo sensore può essere suddiviso in quattro moduli:

sensing module, unità di elaborazione, unità di comunicazione e alimentazione.

1.4.1 Sensing module

In questo contesto indicheremo con il termine sensore l’hardware di cui è dotato un nodo

per trasformare la grandezza fisica acquisita in un segnale elettrico che possa essere

elaborato (trasduttore). Un nodo può disporre di più sensori, anche di grandezze fisiche

diverse, che sono strettamente legate alla specifica applicazione; si possono avere ad

esempio sensori di luminosità, di pressione, di temperatura, di prossimità. La maggior parte

dei sensori, prevede inoltre la presenza di un blocco di conversione analogica-digitale

(ADC, Analog to Digital Converter), da utilizzare durante la fase di acquisizione del

segnale. All’aumentare della velocità di campionamento e del numero di bit del

convertitore analogico digitale, si ha un incremento dei consumi.

Figura 1.3: Architettura del nodo sensore

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

11

1.4.2 Unità di elaborazione

La presenza di una CPU permette di dotare il nodo della capacità elaborativa per gestire le

comunicazioni e le grandezze misurate. Il ruolo della CPU può essere svolto da diverse

tipologie di circuiti logici. Solitamente si preferisce adoperare un microcontrollore a basso

consumo, ma è possibile impiegare anche un FPGA (Field Programmable Gate Array), un

DSP (Digital Signal Processing) o un ASIC (Application Specific Integrated Circuit).

Un compito tipico del microprocessore in queste piattaforme è la verifica dell’effettiva

necessità di utilizzare le risorse: per preservare la carica della batteria il nodo deve

disattivare tutti i dispositivi come chip radio, timer, oscillatori, ogni volta questi non sono

utilizzati per le attività del nodo stesso. La gestione dei tempi e delle modalità del

passaggio dallo stato a basso consumo a quello di attività dei vari componenti è affidata al

microprocessore. Il microprocessore è spesso integrato con alcuni blocchi di memoria

ROM e RAM utilizzati per ospitare il codice eseguibile del sistema operativo e

dell’applicazione, ma immagazzina anche i dati acquisiti dai sensori ed elaborati

dall’applicazione. Alcune piattaforme possono essere dotate di memorie Flash aggiuntive,

connesse al microprocessore per mezzo di interfacce seriali. Queste memorie, solitamente

di capacità superiore rispetto alle memorie integrate con il microprocessore, possono essere

utilizzate per contenere parametri per la configurazione del nodo o altri dati.

1.4.3 Unità di comunicazione

La connessione è realizzata via radio, anche se per alcune particolari applicazioni sono

disponibili soluzioni alternative che impieghino ultrasuoni o comunicazioni ottiche.

Solitamente tra tutti i componenti del nodo, il chip radio è il dispositivo che consuma la

maggior parte dell’energia. Per ridurre il costo e il consumo energetico dei nodi, si

utilizzano tipicamente modulazioni ben consolidate e di bassa complessità, pagando un

costo in termini di capacità trasmissiva che è spesso limitata a qualche decina di kbit/s. Per

limitare ulteriormente il costo finale del dispositivo, la modulazione radio avviene

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

12

normalmente nelle bande comprese tra gli 868-870 MHz o nelle bande ISM (Industrial

Scientific Medical) attorno ai 900 MHz e ai 2,4 GHz, per le quali non è richiesta licenza

governativa.

1.4.4 Alimentazione

Dal momento che non vi è la possibilità di usufruire di una rete di distribuzione

dell’energia, è necessario che ciascun elemento della WSN sia equipaggiato con un sistema

autonomo di alimentazione. Attualmente l’unica soluzione diffusa è data dall’utilizzo di

pile elettrochimiche; questo è uno dei motivi per cui la progettazione delle reti di sensori è

centrata sul risparmio energetico. L’unica strategia di risparmio applicabile per ora è lo

spegnimento selettivo dei nodi per la maggior parte del tempo, in modo da ridurre il

consumo di potenza medio.

1.5 Sistemi operativi per WSN

A differenza delle tradizionali architetture hardware, dove si dispone di grandi quantità di

memoria, di complessi sottosistemi per la gestione dei dati di ingresso e d’uscita, di elevate

capacità di elaborazione e sorgenti di energia praticamente illimitate, nelle reti di sensori ci

troviamo a confronto con sistemi di piccole dimensioni, le cui fonti di energia sono

limitate, vi è scarsa quantità di memoria, e basse capacità di elaborazione. Sono necessarie

quindi soluzioni molto semplici ed efficienti e che soprattutto riducano notevolmente i

consumi di energia. Di conseguenza anche il sistema operativo risente di queste

limitazioni. Infatti un sistema operativo per reti di sensori senza filo deve possedere alcune

caratteristiche di base: deve avere ridotte dimensioni, basso consumo energetico durante

l’elaborazione e consumo pressoché nullo durante lo stato di idle del sensore, deve gestire

la concorrenza, deve implementare protocolli di rete a seconda della periferica di rete

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

13

utilizzata e tali protocolli devono essere poco dispendiosi ; il sistema operativo, inoltre,

deve fornire un’astrazione per i dispositivi hardware montati sul nodo sensore.

Per completezza ricordiamo che in letteratura si distinguono principalmente due approcci

allo sviluppo di sistemi operativi per reti di sensori senza filo:

• Sviluppare un sistema i cui componenti vengono compilati insieme

all’applicazione (come TinyOS (1) ). Questo di fatto consente una singola

applicazione in un dato momento, quindi permette di avere bassissimi

consumi (non esistono 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). Lo svantaggio

derivante da tale approccio è la limitata versatilità e i seri vincoli di

riconfigurabilità dell’applicazione.

• Sviluppare un sistema che includa i tradizionali strati di software dei sistemi

general purpose in versione ridotta (ad esempio Mantis [10]). In questo caso è

difficile tenere sotto controllo i consumi e le risorse impiegate, ma si

guadagna in versatilità, potendo eseguire più applicazioni in contemporanea.

1.5.1 Il sistema operativo TinyOS

TinyOS è un sistema operativo open-source real-time sviluppato per le reti di sensori senza

filo dalla Berkley University di California in collaborazione con il centro ricerche Intel.

TinyOS è concepito in modo da presentare caratteristiche di efficiente gestione energetica,

basso carico computazionale, ridotte dimensioni, modularità e supporto intensivo alla

concorrenza. TinyOS non è un sistema operativo nel senso tradizionale del termine, infatti

si differenzia in modo sostanziale dai sistemi operativi general-purpose in quanto si integra

direttamente con le applicazioni sviluppate. D’altro canto, come tutti i sistemi operativi,

TinyOS gestisce le risorse hardware e software ed esporta allo strato applicativo

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

14

un’astrazione dello strato hardware stabile e consistente, tale da sollevare gli sviluppatori

dall’onere di conoscere i dettagli di basso livello delle risorse fisiche. Una tipica

applicazione TinyOS based ha le dimensioni di una decina di KB, dei quali soltanto 400

byte competono al sistema operativo, ed è proprio alle dimensioni esasperatamente ridotte

che TinyOS deve il suo nome (infatti TinyOS significa sistema operativo piccolo). Tra gli

elementi più significativi di TinyOS spicca il modello di programmazione component-

based, codificato dal linguaggio NesC (un dialetto del C) ed il modello di esecuzione

event-driven come supporto alla concorrenza. TinyOS non possiede un kernel vero e

proprio, ma permette l’accesso diretto all’hardware, attraverso una Hardware Abstraction

Architecture.

E’ opportuno definire brevemente i concetti di task ed evento. Dicesi task un’attività

indipendente mentre l’evento è l’occorrenza di un fenomeno di interesse per uno o più

oggetti. I task sono atomici rispetto agli altri task e possono richiamare comandi, notificare

eventi o attivare altri task all’interno dello stesso componente. In TinyOS gli eventi sono

visti come delle interruzioni hardware: il componente di più basso livello trasforma

un’interruzione hardware in un evento per poi notificarlo ai livelli più alti.

La versione di TinyOS utilizzata per il lavoro di tesi svolto è la 2.0, e si tratta di una

versione successiva a quella adoperata dai precedenti lavori di tesi centrati sulle WSN. Le

novità introdotte, rispetto alla versione precedente, riguardano tre aree fondamentali:

1. Flessibilità e portabilità rispetto alle piattaforme

2. Robustezza ed affidabilità

3. Concetto di distribuzione di servizi

L’accresciuta flessibilità rispetto alle piattaforme è realizzata tramite l’articolazione in tre

layer dell’Hardware Abstraction Architecture e la nuova versione 1.2 del linguaggio NesC.

TinyOS 2.0, inoltre, migliora la robustezza e l’affidabilità ridefinendo alcune tra le

principali astrazioni e politiche delle precedenti versioni tra le quali: il processo di

inizializzazione, la coda dei task e, soprattutto, la gestione energetica. Infine, la nuova

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

15

nozione di distribuzione di servizi, paragonabile ad una API, semplifica notevolmente lo

sviluppo delle applicazioni.

1.5.1.1 Architettura di TinyOS

L’architettura di TinyOS 2.0 si basa sul principio delle astrazioni, attraverso le quali si

realizza una decomposizione in strati verticali ed orizzontali dei componenti del sistema

operativo.

Le astrazioni hardware, lo stack per la comunicazione, quello per i sensori e gli attuatori e

lo strato applicativo sono esempi di strati verticali. Gli strati che occupano, all’interno

dell’architettura del sistema, una posizione più bassa sono dipendenti dall’hardware ed

esportano verso l’esterno complesse interfacce per la gestione dei dispositivi fisici dei nodi

sensori. In modo duale gli strati che occupano posizioni più alte sono perfettamente

disaccoppiati ed indipendenti dai dispositivi fisici ed esportano interfacce più user-friendly.

Figura 1.4: Architettura di TinyOS 2.0

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

16

La decomposizione orizzontale si articola all’interno degli specifici sottosistemi. Essa

semplifica la portabilità, consentendo il riuso delle astrazioni in piattaforme diverse. La

decomposizione orizzontale è particolarmente evidente nello strato che realizza

l’astrazione hardware del nodo sensore. Tale strato infatti riflette perfettamente la

dimensione fisica di un nodo sensore realizzata da una composizione orizzontale di chip

standard. Modellando ciascun chip come astrazione platform-indipendent si abilita la

portabilità dei chip in piattaforme diverse. Al livello più basso dell’architettura del sistema

operativo troviamo l’Hardware Abstraction Architecture, ovvero, i componenti che

realizzano l’astrazione dei dispositivi hardware del nodo sensore.

Dalla figura 1.4 si nota la presenza di due stack differenti: communication stack e sensor

stack (che si riferisce sia ai dispositivi sensori che a quelli attuatori). In particolare i

componenti di più basso livello, che sono a diretto contatto con il canale radio, realizzano

lo stream di dati in uscita suddividendolo in pacchetti. Inoltre essi realizzano attività di

codifica di errori e scheduling del canale di comunicazione. Questi stessi componenti si

occupano, inoltre, della gestione dei pacchetti in arrivo e del loro smistamento nei buffer di

ingresso. I componenti di alto livello si occupano, invece, delle attività di gestione dei

buffer, dell’autenticazione, e realizzano il multiplexing della rete attraverso i diversi

componenti applicativi. Parallelamente al communication stack si sviluppa il sensor stack

che prevede meccanismi per l’interazione con i dispositivi sensori e con gli eventuali

attuatori.

Immediatamente sopra i sensor e comunication stack si collocano i componenti

implementati dall’utente per rispondere alle specifiche esigenze applicative. A livello più

alto troviamo, infine, il componente di sistema Main che include, a sua volta, un altro

componente imprescindibile per ogni applicazione, ovvero, il componente di Scheduler. Il

Main implementa la sequenza di boot del sistema operativo, quindi realizza

l’inizializzazione della piattaforma hardware e dei componenti software ed esegue il main

task loop.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

17

1.5.1.2 Componenti in TinyOS

Il modello di programmazione di TinyOS si basa su una particolare architettura a

componenti. Ciascun componente TinyOS è un’unità software indipendente. In particolare,

ogni componente è descritto in termini delle interfacce importate ed esportate e della sua

implementazione interna.

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 aggiungono una serie di task che vengono

eseguiti ad un livello di priorità basso. Ogni componente inoltre contiene un frame che è

l’area dati del componente e viene allocata staticamente. Tipicamente gli eventi vengono

sollevati da componenti più vicini all’hardware (componenti di basso livello) verso

componenti meno vicini, mentre i comandi vengono invocati in verso opposto. I

componenti possono essere suddivisi in tre categorie: Hardware abstractions, questi

componenti mappano le funzionalità fornite via software sulle funzionalità fornite

dall’hardware creando un’astrazione dello stesso utilizzabile dai moduli superiori;

Synthetic hardware, questi moduli simulano il comportamento di hardware più sofisticato

di quello realmente presente sul sensore; High level software component, questi

Figura 1.5: Rappresentazione di un componente di TinyOS

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

18

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.

1.5.1.3 Il frame

Il frame rappresenta l’area di memoria all’interno del quale il componente conserva i dati

relativi al suo stato. Si tratta, in particolare, di una struttura C-like allocata staticamente in

memoria a tempo di compilazione ed accessibile unicamente al componente stesso. La

preallocazione statica della memoria in fase di compilazione consente di conoscere a priori

la quantità di memoria richiesta dall’intera applicazione, ottimizzando cosi l’uso delle

risorse.

1.5.1.4 I comandi

In TinyOS i comandi sono richieste non bloccanti di servizi offerti dai componenti di

livello inferiore. Generalmente un comando deposita dei parametri all’interno del frame

locale, quindi attiva un task. Alternativamente un comando potrebbe a sua volta invocare

un altro comando di livello inferiore. A causa del limitato quantitativo di memoria del

frame, un componente può rifiutare un comando. Convenzionalmente un comando fornisce

un feedback al suo chiamante per mezzo di opportuni parametri di ritorno, informandolo

così del successo o meno dell’operazione richiesta. I comandi sono progettati nell’ottica di

ritornare immediatamente, svolgendo semplicissime funzioni di triggering su altri

componenti, i servizi richiesti dai comandi saranno, quindi, svolti concorrentemente

all’interno dei task del componente.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

19

1.5.1.5 Gli eventi

In generale, in un modello di programmazione ad eventi, occorre distinguere il concetto di

evento, inteso come accadimento significativo per il quale un’entità ha manifestato

interesse, dal concetto di notifica di un evento, inteso, invece, come annuncio

dell’accadimento di un evento inviato alle entità che hanno manifestato il loro interesse.

Ogni entità interessata ad un particolare evento implementa al suo interno un event

handler, ovvero una routine di gestione dell’evento stesso. In TinyOS gli event handler

sono direttamente o indirettamente legati agli eventi hardware del nodo sensore. Gli eventi

scaturiscono, infatti, da interrupt hardware notificati ai componenti direttamente connessi

con lo strato fisico del nodo. Generalmente un event handler deposita informazioni

all’interno del frame locale, quindi esegue un task. Alternativamente un evento notifica

l’accadimento dello stesso evento ai componenti di livello superiore oppure invoca un

comando di un componente di livello inferiore. Un evento, pertanto, sollecita un processo a

catena in grado di salire e scendere lungo il grafo dei componenti di un’applicazione

innescando attività collaterali. Al fine di evitare possibili cicli infiniti all’interno della

catena comandi/eventi, un comando non può, al suo interno, notificare l’occorrenza di un

evento. Gli eventi sono stati progettati nell’ottica di eseguire piccole quantità di calcoli e,

tipicamente, sono associati a condizioni di risveglio del nodo sensore; per tale motivo, è

necessario che gli eventi vengano eseguiti in tempi brevi, in modo da permettere ai nodi

sensori di ritornare nel loro stato di idle.

1.5.1.6 I task

I task costituiscono l’astrazione con la quale viene definita la mansione primaria di un

componente. I task non hanno diritto di prelazione su qualunque altra attività in corso, in

altri termini sono atomici rispetto agli altri task (politica di run to completition). Per

assicurare la concorrenza, i task possono essere, tuttavia, interrotti dalla notifica di un

evento. Ciascun task può, al suo interno, invocare comandi di componenti di livello

inferiore, segnalare eventi ai componenti di livello superiore, e schedulare altri task.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

20

Mentre il meccanismo dei comandi e degli eventi consente di realizzare computazioni

approssimativamente istantanee, i task non sono time-critical ed abilitano qualunque forma

di computazione che richieda un significativo numero di cicli elaborativi. E’ tuttavia,

fondamentale assicurare la terminazione di un task così da consentire il progresso delle

attività degli altri componenti. L’atomicità dell’esecuzione di un task consente una

notevole semplificazione del modello di concorrenza giacché libera dalla necessità di

protocolli di mutua esclusione per la protezione delle risorse e delle variabili allocate in

memoria da un task. TinyOS gestisce un unico stack allocato, a turno, all’unico task in

esecuzione in un dato istante. Lo scheduler standard di TinyOS esegue i task secondo una

politica FIFO (First In First Out). La CPU viene allocata ad un task solo dopo la naturale

terminazione del task attualmente in esecuzione. Questa scelta non esclude la possibilità di

implementare, secondo le necessità, politiche di scheduling differenti. Esiste, comunque,

un limite alla dimensione della coda dei task nello scheduler legato ai vincoli di memoria;

attualmente il numero di task accodabile è fissato a 255. Oltre ad ottimizzare l’utilizzo

delle risorse hardware, il modello di programmazione event-based limita sensibilmente il

consumo energetico, portando la CPU in uno stato di idle tutte le volte che non ci sono

mansioni da espletare; l’occorrenza di un evento risveglierà dunque la CPU da tale stato.

1.5.1.7 Lo scheduler

Il componente principale, l’unico sempre presente in ogni applicazione, è lo scheduler.

Esso lancia in esecuzione i task dei diversi componenti secondo una politica FIFO run-to-

completion, ossia un task non può interromperne un altro. Lo scheduling ha due livelli di

priorità: quello normale per i task e quello più alto per gli eventi, che possono interrompere

i task. Inoltre esistono livelli di priorità anche tra gli eventi stessi: un evento con priorità

più alta di quello attualmente in esecuzione può interrompere l’esecuzione dell’evento

corrente.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

21

1.5.1.8 Operazioni split-phase

In TinyOS, ogni operazione è una split-phase operation, ovvero l’invocazione di un

servizio e l’operazione di ritorno sono, in realtà, due funzioni separate. Per richiedere un

servizio ad un componente la procedura seguita è quella di invocare un comando sul

componente. Il comando avvia un task e ritorna immediatamente il controllo al

componente chiamante. Al termine del task viene notificato un evento sul componente che

ha richiesto il servizio. Nel modello di interazione split-phase operation, il componente

chiamante non attende attivamente la risposta del componente chiamato (busy waiting), ma

prosegue nelle proprie elaborazioni. Ricevuta poi la notifica dell’espletamento del servizio

con un evento (all’interno del quale possono essere incapsulati dei dati), interrompe

l’esecuzione di eventuali task ed elabora l’evento ricevuto. La semantica delle spilt-phase

operation consente di disaccoppiare il componente chiamante dal componente chiamato,

realizzando, così, un meccanismo di comunicazione asincrona ad accoppiamento lasco.

1.5.1.9 Active Messages

L’ active messages implementa un protocollo inaffidabile di livello data-link che si occupa

del controllo di accesso al mezzo e della comunicazione single-hop tra i nodi della rete.

Questo significa che un nodo equipaggiato con il solo sistema operativo può inviare

messaggi solamente ai nodi direttamente collegati ad esso tramite un mezzo trasmissivo,

mentre non può inviare messaggi a un qualsiasi nodo della rete, perché i protocolli di

routing sono implementati ai livelli superiori. Active messages è una tecnologia molto

leggera, infatti non specifica meccanismi di comunicazione orientati alla connessione, ma

prevede che ogni pacchetto sia un’unità indipendente. Essa consente di inviare pacchetti

verso un singolo nodo, specificando un indirizzo di 16 bit, oppure di inviare pacchetti in

broadcast, specificando l’indirizzo 0xFFFF. Il funzionamento di active messages consiste

nell’inviare al nodo destinazione un pacchetto che, oltre al campo dati, contiene

un’informazione che specifica il tipo di evento che deve essere generato sul nodo

destinazione a seguito della ricezione del pacchetto. Quando un nodo riceve un pacchetto,

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

22

esso viene elaborato dall’active messages, il quale individua il tipo di evento da generare,

incapsula il campo dati del pacchetto in un evento e invia la notifica di tale evento al

componente appropriato. Active messages consente di inviare più di 256 tipi di messaggi

diversi, ognuno dei quali associato a un differente gestore di evento. Questa caratteristica

permette a più reti o a più protocolli di alto livello di funzionare in concorrenza e senza

causare conflitti. Inoltre, l’active messages fornisce anche l’astrazione di 256 gruppi di

nodi differenti. Questa ulteriore funzionalità consente di suddividere una grande rete di

sensori in più sottoreti logicamente separate e tra di loro invisibili. Il sistema di

comunicazione su cui si basa active messages permette di eliminare il complesso utilizzo

di buffer delle implementazioni TCP/IP, ma il principale svantaggio dell’approccio è che

tutti i nodi comunicanti devono avere un componente in grado di gestire un ben preciso

tipo di eventi.

1.5.2 Il sistema operativo Mantis OS

Mantis OS (chiamato anche MOS) è un sistema operativo per reti di sensori senza filo,

progettato e sviluppato dalla Colorado University. Concettualmente MANTIS è opposto a

TinyOS, infatti esso ha la struttura di un sistema operativo general purpose, è organizzato a

livelli, è multithread e contiene uno scheduler preemptive con time slicing, utilizza

meccanismi di sincronizzazione attraverso sezioni in mutua esclusione, ha uno stack

protocollare standard per la rete e device drivers (l’architettura di Mantis verrà analizzata

in dettaglio nel prossimo paragrafo). Grazie al multithread e allo scheduler preempite in

Mantis è possibile, in un nodo sensore, intrecciare l’esecuzione di task complessi con

quella di task che hanno dei requisiti temporali stringenti. L’occupazione di memoria di

Mantis è ridotta infatti in un’immagine che non supera i 500 byte è contenuto il kernel, lo

scheduler e lo stack di rete. Il consumo energetico in Mantis è ridotto in quanto viene

utilizzato uno scheduler efficiente dal punto di vista energetico; infatti quando tutti i thread

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

23

attivi chiamano la funzione sleep() di MOS lo scheduler spegne il microcontrollore

riducendo notevolmente i consumi. Due interessanti caratteristiche di progetto di Mantis

sono: la flessibilità (supporto per piattaforme diverse) e la gestione dei sensori attraverso la

riprogrammazione dinamica da remoto. La versione attuale di Mantis, quella utilizzata per

il lavoro di tesi, è la 1.0 beta.

1.5.2.1 Architettura di Mantis OS

Mantis OS essendo un sistema operativo general-purpose, ha una classica architettura

multithread a strati, come mostrato in figura 1.6. Dalla figura si nota che i thread

applicativi sono separati dal sistema operativo sottostante attraverso le API. Inoltre grazie

alle API, Mantis permette il supporto a piattaforme differenti. Mantis OS (MOS) è

costituito da uno scheduler leggero ed efficiente dal punto di vista energetico, uno stack di

rete a livello utente ed altri componenti come i devide drivers.

Figura 1.6: Architettura di Mantis OS

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

24

1.5.2.2 Kernel e scheduler

Le funzionalità offerte dal kernel di MANTIS OS sono un sottoinsieme dell’interfaccia

POSIX, in particolar modo lo scheduler priority-based basato sull’algoritmo round-robin.

Per la sincronizzazione e la concorrenza il sistema supporta semafori sempre secondo lo

standard posix. L’obiettivo principale per il progetto del kernel di MOS è quello di

implementare questi servizi in modo efficiente sfruttando al meglio le risorse limitate del

nodo sensore. La risorsa più limitata in un nodo Mantis è la RAM. La memoria RAM è

divisa in due sezioni: statica, dove vengono allocate al momento della compilazione le

varabili globali; heap (la parte restante di RAM), dove vengono allocati i thread al

momento dell’esecuzione. Al momento in Mantis non è possibile allocare manualmente

memoria dinamica, questa limitazione è dovuta alle ridotte dimensioni della memoria e alla

necessità di avere una politica di gestione coerente e ben pianificata.

La principale struttura dati globale del kernel è la tabella dei thread che ha un’entry per

ciascun thread. Inoltre dato che questa tabella è allocata staticamente è fissato un numero

massimo di thread (di default è 12 e può essere modificato a tempo di compilazione) e un

livello massimo di overhead di memoria (120 bytes). Ogni entry della tabella occupa 10

byte e contiene: puntatore allo stack corrente, informazioni sui limiti dello stack (puntatore

base e dimensione), un puntatore alla funzione start del thread, il livello di priorità del

thread ed il puntatore al thread successivo (nel caso di utilizzo di una linked list). Il kernel

di Mantis mantiene liste di thread ready separate in base ai diversi livelli di priorità, inoltre

per ogni lista sono mantenuti due puntatori, quello alla testa e quello alla coda; questo

meccanismo semplifica le operazioni di aggiunta e cancellazione dalle liste.

Generalmente il cambiamento di contesto avviene in seguito alla ricezione da parte dello

scheduler di un interrupt temporizzato generato da hardware predisposto, tuttavia si può

avere anche in seguito ad operazioni con i semafori (operazioni in mutua esclusione). Gli

interrupt temporizzati sono gli unici gestiti dal kernel, tutti gli altri sono inviati

direttamente ai device driver associati; al momento il kernel di MOS non supporta interrupt

software.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

25

Oltre ai driver thread e agli user thread c’è anche un idle thread creato dal kernel allo

startup; l’idle thread ha una priorità bassa ed è eseguito quando tutti gli altri thread sono

bloccati e serve a limitare il consumo energetico impostando opportunamente alcuni

parametri del sistema.

1.5.2.3 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 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 di quello MAC che vengono eseguiti dallo stesso thread.

La lettura di un pacchetto di rete funziona con un sistema stop and wait. Infatti un thread

intenzionato a leggere un pacchetto dalla rete (tramite chiamata a mos recv) rimane

bloccato su un semaforo. Quando un pacchetto arriva (è disponibile) viene sollevato un

interrupt, quindi il device driver associato sblocca il semaforo. Non esiste il concetto di

connessione: l’invio e il routing vengono sempre effettuati separatamente per ogni singolo

pacchetto. 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 utilizzati nella particolare rete sviluppata; inoltre è molto utile per la

riprogrammazione dinamica del sensore, in quanto per riprogrammare le funzionalità di

rete è sufficiente bloccare i thread dello stack in esecuzione ed eseguire i thread del nuovo

stack protocollare. Di contro questo sistema è prestazionalmente più scadente di Active

Messages (utilizzato in TinyOS), essendo l’elaborazione del singolo pacchetto più lunga, e

comportando un continuo cambio di contesto di esecuzione al momento della

comunicazione di rete (causando consumi maggiori).

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

26

1.5.2.4 Riprogrammazione dinamica

In base a delle ricerche effettuate, è stato dimostrato che i nodi sensori, dopo che sono stati

messi in esercizio sul campo, necessitano di una riconfigurazione o modifica. In

particolare, dato che le reti di sensori possono essere inserite in aree difficilmente

accessibili, la possibilità di poter effettuare una riconfigurazione dinamica da remoto

semplifica enormemente la gestione della rete. L’obiettivo di Mantis OS è quello di fornire

una riconfigurazione dinamica a differenti granularità: reflash dell’intero OS,

riprogrammazione di un singolo thread e cambiamento di variabili all’interno di un thread.

MOS include due modalità di riprogrammazione: programmazione semplice e

programmazione avanzata. Nella modalità di programmazione semplice, è richiesta la

comunicazione diretta ad un nodo Mantis (ad esempio collegamento attraverso la porta

seriale del sensore), in particolare l’utente deve solo collegare il nodo ad un pc ed avviare

la shell di Mantis. A questo punto (dopo un restart) MOS avvia un boot loader che cerca

eventuali comunicazioni dalla shell, in questo modo il nodo accetterà il nuovo codice

immagine che verrà scaricato dal pc attraverso la connessione diretta. Il boot loader

trasferisce il controllo al kernel di MOS o in seguito ad un apposito comando dalla shell

oppure se durante lo startup non è individuata nessuna shell.

La modalità di programmazione avanzata è utilizzata quando un nodo è stato già messo in

esercizio, di conseguenza tale modalità non richiede un collegamento diretto al nodo

sensore. In particolare, per fornire all’utente la possibilità di gestire i nodi da remoto

Mantis OS include il Mantis Command Server (MCS). Quindi un utente, attraverso un

qualsiasi dispositivo della rete dotato di terminale, può invocare il mantis command client

ed effettuare il login in un nodo sensore. Lo stesso MCS è realizzato come un thread

applicativo, ed è in ascolto sia sulla porta seriale che sull’interfaccia radio di comandi che

possono essere inviati sia dal kernel che dalle applicazioni. L’utente può visualizzare la

lista dei comandi supportati dall’MCS, può ispezionare e modificare la memoria del nodo,

cambiare le impostazioni di configurazione, eseguire o terminare programmi, visualizzare

la tabella dei thread e riavviare il nodo. Al momento MOS supporta solo il login remoto e

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

27

il cambiamento di variabili o parametri mentre è in realizzazione la riprogrammazione

dinamica dell’intero sistema operativo.

1.6 La dependability delle WSN

La dependability è di fondamentale importanza per i sistemi distribuiti e di conseguenza

anche per le reti di sensori senza filo. Essa è costituita da un insieme di attributi, quali:

affidabilità , sicurezza, manutenibilità e disponibilità .

Un sistema può ritenersi affidabile se è realizzato con capacità di rilevazione degli errori

(causati sia da guasti hardware che software), di localizzare ed isolare la causa degli errori

e di ripristinare il sistema.

La dependability si definisce come la capacità di fornire un servizio su cui si può fare

affidamento. Il sistema è quell’entità in grado di interagire con altre entità (es. altri

sistemi); il comportamento del sistema percepito dall’utente rappresenta il servizio, il quale

può ritenersi corretto (proper service) se è fedele alle specifiche funzionali altrimenti è non

corretto e in quest’ultimo caso si parla di malfunzionamento; il confine tra sistema ed

utente si definisce interfaccia e la particolare interfaccia sulla quale viene fornito il servizio

è definita come service interface.

Gli attributi di qualità che costituiscono la dependability sono cinque: Reliability,

Maintainability, Availability, Safety, Integrity. Vengono analizzati di seguito i primi

quattro:

1. Reliability: la reliability è definita come la probabilità che un servizio venga

fornito in modo corretto in un intervallo di tempo finito.

2. Maintainability: la maintainability è definita come la capacità di un sistema di

essere facilmente sottoposto a modifiche o riparazioni. Essa può essere a sua volta

suddivisa in inexpensive maintainance (manutenzione economica ma lenta) e in fast

maintainance (manutanzione rapida ma costosa).

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

28

3. Availability: l’ availability è la probabilità che un sistema sia disponibile in un

determinato istante t. Si definisce dunque un sistema available in un istante t se

esso può fornire un servizio corretto in quel determinato istante.

4. Safety: la safety è la probabilità che in un intervallo di tempo finito non si

presentino condizioni di funzionamento del sistema che possano provocare danni

gravi a persone o cose; in altre parole è la probabilità che non si presentino guasti

catastrofici. E’ chiaro che il concetto di guasto catastrofico è legato alla soggettiva

valutazione dei rischi e dei danni.

1.7 Guasti, errori e malfunzionamenti

Un guasto, fault, è uno stato anomalo dell’hardware e/o del software del sistema che è

conseguenza di un guasto hardware di un componente, di errori di progettazione oppure di

fenomeni quali l’interferenza presente tra due o più sensori.

I guasti e le loro cause possono essere molto diversi; essi vengono classificati secondo la

loro natura (guasti accidentali ed intenzionali), la loro origine (guasti fisici, guasti causati

dall’uomo, guasti interni, guasti esterni, guasti di progetto e guasti operativi) e la loro

persistenza (guasti permanenti e transienti).

Un errore, error, è lo stato corrotto del sistema, conseguenza di un fault temporaneo, che

può portare al fallimento di questo ovvero alla fornitura di un servizio non corretto. Quindi

un errore è causato da un fault cioè da un guasto. In alcuni casi un fault può causare più di

un solo errore. Inoltre un errore può essere latente o rilevato. Un errore si dice latente

(latent error) quando non è stato riconosciuto come tale; un errore, al contrario, può essere

rilevato (detected error) da un algoritmo o meccanismo di rilevamento apposito.

Infine è opportuno definire anche il significato di failure. Un fallimento, failure, è definito

come l’evento in corrispondenza del quale il sistema non fornisce più un servizio corretto

(proper service, ossia un servizio conforme alle specifiche). Quindi avendo definito fault,

error e failure è lecito definire che un guasto è attivato nel momento in cui esso genera un

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

29

errore, mentre si può definire propagazione di un errore il raggiungimento dell’interfaccia

del sistema e la generazione di un malfunzionamento. Si può asserire, quindi, che vi è una

catena che lega i guasti gli errori ed i malfunzionamenti:

1.7.1 Faults nel nodo sensore

Nel lavoro di tesi concentreremo l’attenzione in particolar modo ai guasti nei singoli nodi

sensore dal momento che il tool simula un guasto che potrebbe verificarsi in un generico

sensore di una WSN. I guasti di un sensore possono essere classificati in transienti e

permanenti. I primi sono legati a momentanee condizioni fisiche e si eliminano

definitivamente senza ricorrere ad alcuna procedura di recovery. I guasti transienti

generano soft errors: essi sono errori che si manifestano nella memoria di un calcolatore in

cui avviene una modifica ad un’istruzione di un programma o ad un valore di un dato.

Sebbene un soft error alteri il contenuto di una cella di memoria, esso non è in grado di

danneggiare l’hardware di un sistema a differenza degli hard error. I guasti permanenti,

invece, sono stabili e continui nel tempo. Si provi ad immaginare l’esaurimento di una

batteria di un nodo sensore come un caso di guasto permanente. Studi sperimentali [6]

hanno dimostrato che l’80% dei malfunzionamenti di un sistema informatico sono

provocati da guasti transienti nelle celle di memorie o nei registri del processore. Inoltre i

guasti transienti sono provocati da cause fisiche quali le cadute di tensione, il crosstalk

(disturbo del segnale) e l’urto di particelle cosmiche. L’attenzione deve essere

particolarmente rivolta ai soft errors poiché l’evoluzione della tecnologia elettronica ha

Figura 1.7: Legame tra fault, error e failure

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

30

aumentato la complessità dei circuiti integrati favorendo così la perturbazione di particolari

fenomeni atmosferici che prima venivano considerati ininfluenti. Un tipico

malfunzionamento generato dalla propagazione dei soft errors prende il nome di bit-flip o

anche single-event upset. Il fenomeno del bit-flip è caratterizzato da una temporanea

inversione di un bit. Si verifica uno switch del bit: se il suo valore è 0 allora diventa 1 e

viceversa. Occorre tenere ben presente il concetto di bit-flip perché questo fenomeno è alla

base della tecnica di fault injection adottata dal tool.

E’ importante sottolineare l’assenza di circuiti di ridondanza e di controllo di errore

all’interno del microcontrollore del nodo sensore. Tale scelta è legata ai vincoli di

progettazione del sensore privilegiando la semplicità dell’architettura in modo tale da

ridurre sia il consumo energetico, sia le dimensioni ed anche il costo.

1.8 Valutazione della dependability

La tecnica di valutazione della dependability più interessante per il lavoro di tesi svolto è la

fault forecasting che consente di stimare il numero, la frequenza di incidenza, presente e

futura, e le conseguenze dei guasti. L’obiettivo del fault forecasting è di effettuare una

stima del numero corrente dei fault, stimarne la futura incidenza e le possibili conseguenze.

Vi sono due approcci che possono essere intrapresi: approccio deterministico ed approccio

probabilistico. Il primo ha lo scopo di capire gli effetti dei guasti sul malfunzionamento del

sistema. Il secondo, essendo aleatorio, verte a stimare i parametri della dependability. Una

stima quantitativa del grado di dependability di un sistema può essere ottenuta calcolando

alcuni parametri sintetici tra cui quelli riportati e descritti nella seguente tabella:

Parametro Acronimo Descrizione

Mean Time To Crash MTTC Tempo medio per avere un crash del sistema

Mean Time Between Crashes MTBC Tempo medio tra due crash successivi del

sistema

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

31

Mean Time To Failure MTTF Tempo medio per il verificarsi di un failure

Mean Time Between Failure MTBF Tempo medio tra due failure successivi

Mean Number of Instruction to

Restart

MNIR Numero medio di istruzioni per il ripristino

del sistema

Mean Time To Repair MTTR Tempo medio necessario a riparare il

sistema

Mean Down Time MDT Tempo medio in cui il sistema non è

funzionante

Mean Time Between Errors MTBE Tempo medio tra due errori successivi

In fase di progettazione, design phase, lo studio dell’affidabilità del sistema può essere

condotto utilizzando un software di simulazione: il sistema è sottoposto a situazioni di

errore (simulated fault-injection) con il duplice obiettivo di individuare eventuali

dependability bottlenecks e di stimare la coverage dei meccanismi di fault tolerance. I

feedback derivanti dallo studio delle reazioni del sistema risultano particolarmente utili ai

progettisti ai fini di un miglioramento del sistema.

E’ possibile valutare la dependability analizzando il comportamento di un sistema in

risposta a contesti reali: un approccio di questo tipo, noto come field failure data analysis

(FDDA), consente di ottenere informazioni relative esclusivamente agli errori rilevati

durante il periodo di osservazione e la caratterizzazione statistica che se ne può dedurre.

L’analisi della dependability di un sistema basata su un approccio di tipo measurement-

based si articola in quattro fasi successive: elaborazione dei dati, identificazione del

modello e stima dei parametri, soluzione del modello, analisi del modello e misure.

Tabella 1.1: Parametri per valutare la dependability

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

32

Capitolo 2

Fault injection

La tecnica della fault injection è spesso adoperata per tracciare una stima della

dependability di un sistema.

La fault injection si presta ad essere molto utile per testare l’efficienza dei meccanismi di

fault tolerance ma soprattutto il grado di dependability del sistema. Con l’ausilio di un

simulatore è possibile iniettare particolari guasti, raccogliendo le informazioni sui loro

effetti. Inoltre la fault injection è adoperata per testare la fault detection, la fault isolation e

le capacità di recovery del sistema.

In particolare la fault detection mira a scoprire un guasto sia a livello hardware che a

livello software. Le tecniche di fault detection solitamente comunicano all’utente la

necessità di operare mediante interventi manuali oppure l’inizio di una procedura di

ripristino automatico.

La fault isolation, invece, mira a determinare la causa di un problema generato da un

guasto. Tale tecnica è anche nota col termine fault diagnosis sia a livello hardware che a

livello software.

Spesso si tende ad usare i termini fault isolation e fault detection come sinonimi ma ciò

non è corretto. Fault detection si usa quando si è verificato un problema ed è stato rilevato;

mentre fault isolation quando si individua la causa precisa del guasto e la sua locazione

(senza correggerlo).

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

33

2.1 Tecniche di fault injection

La fault injection può essere realizzata seguendo due livelli di astrazione: a livello

hardware, utilizzando un hardware aggiuntivo (injector); a livello software attraverso degli

strumenti software. La scelta del livello di astrazione da adottare per eseguire la fault

injection è legata allo scopo che si vuole raggiungere. Se si è interessati ad esempio ad un

guasto di tipo stuck-at-faults, è preferibile un’iniezione di tipo hardware potendo così

controllare direttamente la locazione del fault.

I guasti di tipo stuck-at-faults hanno la caratteristica di forzare un valore in modo

permanente in un punto del circuito che può essere rappresentato o da un segnale oppure

da un registro.

La scelta di non usare metodi software di fault injection per fault permanenti nasce dal

fatto che l’esecuzione dell’iniezione non sarebbe molto pratica. Al contrario, se si vuole

alterare un dato, la tecnica software viene in aiuto. Infatti alcuni faults come i bit-flip nelle

celle di memoria possono essere realizzati sia mediante tecniche software che hardware.

Si analizza ora nei dettagli la tecnica hardware di fault injection.

2.1.1 Hardware-Implemented fault injection

La tecnica di Hardware-Implemented fault injection o brevemente denominata HWIFI

viene adoperata per effettuare l’iniezione di faults nell’hardware di un sistema ed

esaminarne gli effetti. Solitamente l’hardware su cui si effettua l’iniezione è costituito da

circuiti VLSI (Very Large Scale Integration) e si tratta di iniezione a livello transistor.

La tecnica HWIFI è utile per testare un circuito dopo che è stato realizzato e verificarne il

suo corretto funzionamento; il circuito viene collegato ad un apparecchio che esegue il

testing su di esso; dopo che è stato iniettato il guasto, viene esaminato il suo

comportamento e si verifica se è corretto (conforme alle specifiche). La procedura descritta

può richiedere del tempo, tuttavia il tempo richiesto per il testing è di gran lunga inferiore a

quello necessario per una simulazione.

Ma la fault injection a livello hardware presenta dei limiti:

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

34

• accessibilità limitata a livello pin: i fault injectors (gli iniettori di guasti)

hardware non possono iniettare guasti nei registri e nella cache.

• costo implementativo extra: per facilitare la fault injection hardware è

richiesto un hardware dedicato per l’iniezione.

2.1.2 Software-Implemented fault injection

La tecnica di fault injection implementata a livello software, più comunemente nota con

l’acronimo SWIFI (Software Implemented Fault Injection), fa uso di appositi strumenti

software per realizzare un’iniezione.

La scelta di questa tecnica spesso risulta vantaggiosa quando non è possibile utilizzare

quella hardware per testare applicazioni e sistemi operativi. Inoltre la tecnica SWIFI non

richiede alcun hardware dedicato e pertanto è conveniente.

I fault injectors SWIFI, dunque, offrono una maggiore flessibilità e semplicità

nell’implementazione della fault injection. L’obiettivo delle tecniche SWIFI è modificare

lo stato hardware/software del sistema attraverso un controllo software che forza il sistema

a comportarsi come se fosse in presenza di un guasto hardware.

Sebbene le tecniche SWIFI siano vantaggiose rispetto alle tecniche HWIFI, esse

presentano alcune problematiche:

• Problema di portabilità

Il carico di lavoro per la migrazione verso nuovi sistemi è abbastanza

oneroso. Il costo per implementare un modello di guasto molto semplice è alto

poiché il programmatore deve scrivere del codice aggiuntivo sia per

coordinare l’esperimento eseguito sui nuovi sistemi, e sia per riportare i

risultati ottenuti.

• Problema del riuso dei componenti

Un componente non è riusabile. Vi è incompatibilità tra componenti di tool

diversi.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

35

• Scarsa flessibilità del metodo di iniezione

Dal momento che nessun tool supporta modelli di guasto molteplici, è

necessario utilizzare un nuovo tool ogni volta che si vuole usare un nuovo

modello di guasto. Diventa quindi poco pratico dover adattare tanti tool, uno

per ogni modello di guasto, a nuovi sistemi. Inoltre ogni tool possiede la

propria interfaccia per configurare gli esperimenti e quindi anche se i tool

venissero usati senza necessità di adattamenti dai nuovi sistemi, ci sarebbe

comunque da considerare un tempo aggiuntivo necessario per il loro

apprendimento.

2.1.3 Fault injection a tempo di compilazione e a tempo di esecuzione

La fault injection a tempo di compilazione inietta faults modificando il codice sorgente del

programma per emulare gli effetti dei guasti hardware, software e transienti.

Un primo metodo è chiamato code mutation che altera le linee del codice che contengono i

faults. Vediamo un esempio semplice di questa tecnica:

Prima: a = a + 1

Dopo: a = a - 1

Un secondo metodo vicino alla code mutation è la code insertion che a differenza del

primo non modifica ma aggiunge codice, attraverso l’utilizzo di una funzione perturbatrice.

Si tratta di una semplice funzione che prende un valore e lo perturba trasformandolo in un

altro valore. Il codice seguente è un semplice esempio che mette in mostra la tecnica

descritta:

int pFunc(int value) {

return value + 20;

}

int main(int argc, char * argv[]) {

int a = pFunc(aFunction(atoi(argv[1])));

if (a > 20) {

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

36

/* do something */

} else {

/* do something else */

}

}

In questo caso pFunc è la funzione perturbatrice che influisce sul valore di ritorno value ed

introduce il fault nel sistema.

La tecnica di compile-time injection non consente però l’iniezione di guasti in modo

interattivo quando cioè il programma è in esecuzione.

Le tecniche di run-time injection fanno uso di trigger software per iniettare un guasto in un

applicativo di sistema in esecuzione. Questi trigger software possono essere implementati

in diversi modi: time-based (quando in un determinato istante viene generata

un’interruzione che consente l’iniezione del guasto); interrupt-based (si adoperano

eccezioni hardware e meccanismi di trap software per generare interruzioni in un punto

specifico del codice o per un particolare evento del sistema come ad esempio l’accesso ad

una specifica locazione di memoria).

Le tecniche di run-time injection possono utilizzare differenti tecniche per l’iniezione di

guasti in un sistema:

• Corruzione dello spazio di memoria: questa tecnica consiste nella

corruzione della RAM, dei registri del processore e della memory-mapped

I/O.

• Tecniche di corruzione delle system calls: il fault si propaga dalle interfacce

del kernel del sistema operativo al software in esecuzione nel sistema.

Vengono intercettare le system calls del sistema operativo fatte dal software a

livello utente e si iniettano i guasti in queste.

• Fault injection a livello rete: questa tecnica è legata alla corruzione, perdita

o riordinamento dei pacchetti di rete.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

37

2.1.4 Fault injection a livello assembly

Iniettare dei guasti a livello assembly può rivelarsi una buona scelta per creare dei SEU

(Single-Event-Upset) e studiarne le conseguenze sul sistema, inoltre è una buona tecnica

anche per valutare l’affidabilità di sistemi operativi differenti.

I SEU sono dei cambiamenti di stato dei dispositivi microelettronici, causati da fenomeni

fisici.

La tecnica della fault injection a livello assembly, a differenza di quella SWIFI, opera ad

un livello di astrazione più basso e pertanto presenta un notevole vantaggio: è possibile

operare sul singolo bit di un registro, sporcando il valore in esso contenuto. Inoltre

l’iniezione viene eseguita con maggior precisione e il programmatore conosce esattamente

il punto di iniezione (la locazione) in modo da poter prevedere le conseguenze del fault

iniettato.

Bisogna però prestare attenzione per utilizzare al meglio questa tecnica. Infatti il tipico

utilizzo dell’injection a livello assembly prevede una scelta casuale del punto di iniezione.

Ma così facendo si rischia di rendere la tecnica poco proficua in quanto molti dei fault

iniettati potrebbero non essere mai attivati: si pensi all’iniezione di un valore errato in un

registro prima che questo venga scritto dall’istruzione successiva oppure all’iniezione di un

fault in un’area di memoria che non verrà mai utilizzata.

2.2 Descrizione della tecnica SWIFI utilizzata e modifiche apportate

Di seguito, inizialmente descriviamo la tecnica SWIFI che è stata introdotta da Aiello nel

suo lavoro di tesi [7] e poi utilizzata da Testa nella versione 1.0 dell’AVR-INJECTION

Tool [9]; successivamente presentiamo le modifiche apportate nella versione 2.0

dell’AVR-INJECTION Tool.

2.2.1 Descrizione della tecnica di injection

Il modello dei fault adottato è del singolo bit-flip noto anche come Single Event Upset

(SEU). Tali fault possono essere iniettati nei registri del processore, nella memoria dati e

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

38

nell’area codice tramite l’utilizzo di istruzioni assembly. Si utilizza inoltre la tecnica di

inserzione del codice, aggiungendo delle istruzioni al programma che richiamano la fault

injection prima di eseguire particolari istruzioni.

Si parte innanzitutto dall’analisi del sistema fault free che consiste nello studio del sistema

originario, cioè la golden copy. Questo studio è fondamentale per la pre-injection ovvero la

fase di conoscenza del flusso di esecuzione e delle risorse utilizzate dal sistema evitando

così l’iniezione di guasti che non verranno mai attivati.

Per settare un esperimento occorre fornire informazioni sul cosa, dove e quando iniettare i

guasti. Il cosa è rappresentato dai SEU (ovvero i bit-flip). Per dove s’intende o la memoria

dati o l’area codice oppure i registri del microcontrollore (su cui si sta applicando la fault

injection). Immaginando che l’istruzione target (istruzione in cui iniettare il fault) sia

eseguita n volte, per quando si intende l’istante in cui viene applicata l’iniezione,

precisamente una tra le n esecuzioni dell’istruzione stessa.

E’ stata scelta la tecnica di inserzione del codice poiché, diversamente dal metodo di

modifica del codice, essa realizza la fault injection durante l’esecuzione del programma

aggiungendo nuove istruzioni invece di modificare quelle esistenti. Il codice creato per fare

fault injection, a differenza di quello della golden copy, presenta dopo l’istruzione di uscita

(<exit>) tre blocchi di codice assembler chiamati: CheckInjection, Injection e

InstructionTarget. Il blocco CheckInjection consente di poter controllare l’istante di

iniezione di un guasto, infatti attraverso un’istruzione di confronto, si verifica se è stato

raggiunto o meno tale istante; in caso affermativo si effettua un salto al blocco di Injection.

Il blocco Injection contiene le istruzioni per effettuare l’iniezione vera e propria. In questo

blocco interviene il registro maschera realizzato per sporcare un particolare bit mediante

un’operazione di xor con il registro vittima dell’iniezione. Conclusa l’iniezione si ritorna al

blocco CheckInjection il quale dopo aver concluso le proprie operazioni effettua un salto al

blocco InstructionTarget. Questo blocco svolge un ruolo di collegamento tra l’esecuzione

dell’applicazione e l’esecuzione dell’iniezione; consente il salto al blocco CheckInjection

e, conclusa l’iniezione, garantisce il proseguimento dell’esecuzione dell’applicazione

affetta dal fault.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

39

2.2.2 Guasti

I fault prodotti dalle procedure sono stati divisi in base al loro punto di iniezione:

• Memoria dati

• Codice

• Registri del processore

2.2.3 Guasti in memoria dati

Per quanto riguarda la memoria, l’idea è stata quella di alterare il valore di una locazione

nell’area dati statica prima che essa venga letta da un’istruzione target. Un esempio pratico

può essere utile per fissare le idee. Si pensi ad un’istruzione target in cui iniettare il fault

come una lds (istruzione di load) che carica un valore contenuto nell’area dati statica in

uno dei registri del microcontrollore (es. r24). Ad esempio considerando l’istruzione target

lds r24, 0x0130 il codice per l’injection sarà il seguente:

lds r24, 0x0130 ; load diretto dallo spazio dati (istr. target)

push r16 ; push nello stack

ldi r16,0x20 ; load immediato nel registro

eor r24,r16 ; xor tra registri

sts 0x0130, r24 ; store diretto verso lo spazio d ati

pop r16 ; pop dallo stack

Si effettua il push di r16 per non sovrascrivere il valore originale dal momento che questo

registro è utilizzato come maschera. Si esegue la xor logica tra la maschera e il valore letto

dalla memoria simulando così il guasto di tipo bit-flip e successivamente in memoria si

memorizza mediante l’operazione di store il valore sporcato.

Un altro caso di guasto in memoria è l’alterazione dell’area dati relativa allo stack in

quanto l’area dati è suddivisa in due porzioni: area dati ottenuti dall’applicazione e area

stack. A tal proposito si riporta un esempio di una procedura assembler per l’injection:

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

40

pop r28 ; pop dallo stack (istruzione target)

push r16 ; push nello stack

ldi r16,0x02 ; load immediato nel registro

eor r28,r16 ; xor tra registri

pop r16 ; pop dallo stack, ripristino valore prec edente del r16

push r28 ; push nello stack del valore sporcato

Tale procedura sostituisce l’istruzione pop r28 leggendo il valore memorizzato nello stack,

sporcandolo mediante un’operazione di xor e inserendo il nuovo valore nello stack.

2.2.4 Guasti nel codice

Sono stati presi in analisi solo fault relativi agli operandi evitando di modificare il codice

operativo dal momento che esiste un’opportuna routine del processore per gestire

l’eccezione sollevata. Un esempio di procedura di injection nel caso di guasto nel codice è

la seguente:

ldi r24, 0x05; load immediato nel registro

push r16 ; push dallo stack

ldi r16,0x20 ; load immediato nel registro

eor r24,r16 ; xor tra registri

pop r16 ; ripristino del valore precedente nel re gistro r16

La procedura mostrata nell’esempio altera il valore dell’operando immediato caricato nel

registro r24.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

41

2.2.5 Guasti nei registri del processore

L’ultimo gruppo di faults è riservato alla modifica dei valori presenti nei registri del

processore soffermando l’attenzione sul registro Program Counter (PC) e sul registro

Status Register (SR).

Per realizzare un guasto nel Program Counter è sufficiente realizzare un injector che

contenga una semplice istruzione di salto incondizionato come jmp, rjmp, ijmp, ed ejmp.

Vediamo un esempio:

jmp 0x1a9c ;indirizzo istruzione target con il 5 bi t modificato

Per quanto riguarda lo Status Register, è sufficiente utilizzare una delle istruzioni

disponibili per modificare i flag dello status register e cioè: bset k e bclr k che settano

rispettivamente ad 1 e a 0 il k-esimo bit del registro di stato oppure sec, clc, sen, cln, sez,

clz, sei, cli, ses, cls, sev, clv, set, clt, seh e clh che settano i flag dello Status Register.

2.2.6 Tecnica per la rilevazione dell’istante di injection

Individuata la procedura di injection, occorre stabilire quando essa deve essere invocata dal

momento che potrebbe essere eseguita più volte all’interno di un programma target. Inoltre

è difficile che lo stesso SEU si presenti più volte nel corso di una sola esecuzione del

programma target.

Il diagramma di flusso in figura 2.1 illustra il principio della tecnica. Occorre concentrarsi

sulla logica del rombo presente nel diagramma di flusso riportato. Tale logica è stata

definita mediante la seguente procedura assembly che aggiunge al codice dell’applicazione

un overhead trascurabile:

push r16 ; salvataggio nello stack del valore del r egistro r16

in r16,sreg ; lettura dello status register

push r16 ; salvataggio status register nello stac k

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

42

lds r16,0x0131

cpi r16,0x55 ; confronto del valore letto con l’ immediato 0x55

breq .+72 ; salta, se il valore immediato `e pres ente in r16

lds r16,0x0EC1;

cpi r16,0x55 ; confronto del valore letto con l’ immediato 0x55

breq .+66 ; salta, se il valore immediato `e pres ente in r16

lds r16,0x0CC1

cpi r16,0x55 ; confronto del valore letto con l’ immediato 0x55

breq .+60 ; salta, se il valore immediato `e pres ente in r16

lds r16,0x0132 ; load del valore di avvenuto init del conteggio

cpi r16,0x55 ; confronto del valore letto con l’ immediato 0x55

breq .+16 ; salta, se il valore immediato `e pres ente nel r16

ldi r16,0x55 ; load immediato 0x55 nel registro r 16

sts 0x0132,r16 ; store del valore 0x55 nella memo ria

ldi r16,0x03 ; inizializza il contatore con il nu mero di cicli

sts 0x0133,r16 ; store del valore del contatore

jmp 0x2382 ;

lds r16,0x0133 ; load del valore del contatore

dec r16 ; decrementa il contatore

sts 0x0133,r16 ; aggiorna il valore del contatore

tst r16 ; verifica se il contatore è arrivato a z ero

brne .+18 ; salta, se il valore immediato non è p resente nel r16

ldi r16,0x55 ; load immediato 0x55 nel registro r 16

sts 0x0131,r16 ; store del valore 0x55 nella memo ria

sts 0x0CC1,r16; store del valore 0x55 nella memor ia

sts 0x0EC1,r16; store del valore 0x55 nella memor ia

jmp 0x238A ; invocazione della procedura di injec tion

pop r16 ; lettura dallo stack del vecchio status register

out sreg,r16 ; ripristino del valore dello status register

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

43

pop r16 ; ripristino del valore iniziale del regi stro r16

In tale procedura inizialmente avviene il salvataggio del valore dello Status Register in

modo da conservare il suo valore durante l’esecuzione della procedura di controllo; poi si

effettua un controllo in memoria per verificare se l’injection è stata già effettuata ed il

controllo, per aumentare l’affidabilità, viene ripetuto in altre locazioni non contigue

(0x0131,0x0CC1 e 0x0EC1), diminuendo così la probabilità di sporcare l’area di memoria

utilizzata per il controllo.

Vi è inoltre un controllo del ciclo in cui iniettare un guasto, la prima volta che la procedura

è richiamata si verifica l’inizializzazione del contatore di cicli inserendo il valore del

contatore di ciclo nella locazione 0x0133. Se l’iniezione non è stata ancora effettuata si

decrementa il valore del contatore e quando si raggiunge il valore zero si fa la chiamata

alla procedura di injection (effettuando la vera e propria iniezione).

Main Program

Instruction Target

Inj.?

Injection Block

YES

NO

Figura 2.1: Procedura per l’individuazione dell’istante di injection

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

44

Tale tecnica si rivela molto utile poiché è possibile specificare l’istante in cui effettuare

l’iniezione e si evita che qualche malfunzionamento modifichi il valore di avvenuta

injection (sfruttando la presenza ridondante di tale valore in tre locazioni non contigue).

2.2.7 Modifiche apportate

Un primo problema riscontrato nella tecnica di injection, utilizzata nella versione 1.0

dell’AVR-INJECT Tool realizzato da Testa nel suo lavoro di tesi [9], consiste nella scelta

statica delle locazioni di memoria in cui salvare le informazioni di controllo. In particolare

questa scelta non si addice alla caratteristica di generalità del tool, infatti al variare

dell’applicazione varia il codice e di conseguenze le locazioni scelte potrebbero coincidere

con locazioni richiamate dall’applicazione stessa provocando dei conflitti. Per risolvere

questo problema è stato modificato il tool, in questo modo ogni volta che viene caricata

una nuova applicazione le locazioni necessarie a contenere le informazioni di controllo

sono scelte dinamicamente, ed in modo casuale, tra quelle che non sono mai utilizzate

dall’applicazione stessa.

Un altro problema è stato riscontrato nella tecnica per l’individuazione dell’istante di

injection, infatti quando viene inizializzato il registro contatore (e cioè la prima volta che

viene eseguita l’istruzione target) esso non viene decrementato, questo comporta che

l’iniezione viene effettuata con un ciclo di ritardo; ad esempio se l’utente volesse

effettuare l’iniezione durante la prima esecuzione dell’istruzione target l’iniezione vera e

propria avverrebbe luogo solo durante la seconda esecuzione dell’istruzione target. Per

risolvere questo problema il registro contatore è stato inizializzato con il valore di ciclo già

decrementato ed è stato inserito un controllo aggiuntivo per la verifica del raggiungimento

dell’istante di injection. Riportiamo di seguito la procedura per l’individuazione

dell’istante di injection modificata:

push r16

in r16, sreg

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

45

push r16 ; Saving SR

lds r16, loc1

cpi r16, 0x55

breq .+76 ; ->Exit

lds r16, loc2

cpi r16, 0x55

breq .+68 ; ->Exit

lds r16, loc3

cpi r16, 0x55

breq .+60 ; ->Exit

lds r16, loc4

cpi r16, 0x55

breq .+20 ; ->Exit

ldi r16, 0x55

sts loc4, r16

ldi r16, val; ->Initialize the counter with the n umber of cycles

sts loc5, r16

tst r16

breq .+18 ; ->Ciclo Injection

jmp loc_exit ; -> Exit

lds r16, loc5 ; -> Verify count

dec r16

sts loc5, r16 ; -> Update the value of the counte r

tst r16

brne .+18 ; ->Exit

ldi r16, 0x55

sts loc1, r16

sts loc2, r16

sts loc3, r16

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

46

call loc_injection ; ->Injection

pop r16 ; -> Exit

out sreg, r16 ; -> Recovery SR

pop r16

ret

Dove abbiamo indicato con loc1, loc2, loc3, loc4 e loc5 le locazioni calcolate

dinamicamente dal tool ; con val il valore del ciclo di iniezione scelto dall’utente; con

loc_exit la locazione in cui si effettua il ripristino dello status register e con loc_injection

la prima locazione del blocco Injection.

Un altro errore riscontrato nel meccanismo di iniezione è relativo al calcolo automatico

delle locazioni, infatti sia per l’istruzione target che per quella successiva è sempre

considerata un’occupazione di memoria pari a due byte; tuttavia nell’instruction set del

microcontrollore AVR ATMega128L (microprocessore del sensore wireless mica2) sono

presenti anche istruzioni a quattro byte. Per risolvere questo problema è bastato fare un

controllo sul codice operativo delle istruzioni, discriminando quelle di quattro byte dalle

altre di due byte, durante il calcolo automatico delle locazioni.

Un ulteriore problema affrontato è stato quello delle istruzioni non idempotenti (ad

esempio l’istruzione add). In particolare, nella versione precedente, l’istruzione target

(quella in cui si vuole effettuare l’iniezione) è eseguita sia all’interno del blocco

InstructionTarget che nel blocco di Injection, provocando inevitabilmente problemi con le

istruzioni che per loro natura non sono idempotenti. Per risolvere questo problema si sono

modificati i blocchi di Injection e di InstructionTarget per le istruzioni non idempotenti;

più precisamente nel blocco di Injection non è più eseguita l’istruzione target ma avviene

solo la modifica del suo operando (attraverso l’operazione di xor) mentre nel blocco di

InstructionTarget l’esecuzione dell’istruzione target è stata posticipata rispetto alla

chiamata della procedura CheckInjection. Per chiarire ulteriormente il meccanismo, di

seguito riportiamo le sezioni di Injection e InstructionTarget relative ad un’istruzione

target non idempotente:

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

47

<Injection>:

push r16

ldi r16, 0x1 ; -> Loading mask

eor r24,r16 ; -> Register with bit-flip

pop r16

ret ;-> Return to CheckInjection

<InstructionTarget>:

call loc_CheckInj ; -> Jump to CheckInjection

subi r24,0x74 ; -> Instruction to be flipped

sbci r25, 0xFF ; -> Next instruction

jmp loc_main_program; -> Return to main program

Un’ulteriore modifica apportata alla tecnica di injection è quella relativa all’iniezione dei

faults nel registro di stato (Status Register), in particolare nella versione precedente

l’iniezione del guasto avveniva azzerando semplicemente uno dei bit del registro di stato;

tuttavia qualora il valore del bit scelto fosse già zero allora l’iniezione non sarebbe stata

effettuata. Per risolvere questo tipo di problema abbiamo modificato i blocchi di

InstructionTarget ed Injection in modo tale da cambiare opportunamente il valore del bit

del registro di stato selezionato dall’utente. Di seguito riportiamo le sezioni modificate:

<Injection>:

push r16

ldi r16, 0x1 ; -> Loading mask

eor r28, r16 ; -> Register with bit-flip

pop r16

ret ;-> CheckInjection

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

48

<InstructionTarget>:

push r28

in r28, sreg

call loc_CeckInj ; -> Jump to CheckIn jection

out sreg, r28 ; -> Recovery SR

pop r28

adc r25,r25 ; -> Instruction to be flipped

add r24, r18 ;-> Next instruction

jmp loc_main_program

In particolare dalla sezione InstructionTarget si vede come in primo luogo viene salvato

nello stack il contenuto del registro r28, il quale verrà utilizzato come registro di appoggio

per salvare il contenuto del registro di stato; si effettua poi il salto alla sezione

CheckInjection per verificare se è stato raggiunto il ciclo in cui iniettare il fault ed in caso

affermativo viene modificato il bit del registro r28. Quindi quando dalla sezione

CheckInjection si ritorna alla sezione InstructionTarget viene caricato nel registro di stato

il contenuto del registro r28 (tale contenuto è stato modificato solo se è stata effettuata

l’iniezione del fault), viene ripristinato il valore originario del registro r28 e viene eseguita

l’istruzione target (è da notare che, in caso di iniezione del fault, viene modificato il

contenuto del registro di stato prima dell’esecuzione dell’istruzione target in quanto tale

istruzione utilizza il valore di un particolare bit del registro di stato).

Infine rispetto alla versione precedente è stata ampliata la tipologia dei fault relativi ai

registri del processore, infatti oltre ai fault nel PC e nel registro di stato sono stati

introdotti i fault nello stack pointer (registro SP).

Riportiamo di seguito le sezioni di Injection e InstructionTarget relative a questa

particolare tipologia di faults:

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

49

<Injection>:

push r16

ldi r16, 0x1 ; -> Loading mask

eor r28, r16 ; -> Register with bit-flip

pop r16

ret ;-> CheckInjection

<InstructionTarget>:

push r16

push r28

in r28, spl

call loc_CheckInj ; -> Jump to CheckInje ction

lds r16, loc1

cpi r16, 0x55

brne .+20 ; ->Recovery SP

mov r16, r28

pop r28

sts loc1, r28

mov r28, r16

pop r16

out spl, r28 ; -> Modify SP

lds r28, loc1

rjmp .+4

pop r28

pop r16

push r28 ; -> Instruction to be flipped

push r29 ;-> Next instruction

jmp loc_main_program

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

50

Dalla sezione InstructionTarget si nota come in primo luogo vengono salvati nello stack i

valori dei registri r28 ed r16 che sono successivamente utilizzati come registri di

appoggio, infatti nel registro r28 viene salvato il contenuto del registro SP (dato che il

registro SP è a 16 bit è l’utente che decide se modificare un bit della parte alta o della parte

bassa del registro; nell’esempio l’utente ha deciso di modificare la parte bassa) mentre il

registro r16 è utile per verificare se è stata effettuata o meno l’iniezione del fault . In

particolare se l’esecuzione corrente non è quella relativa al ciclo di iniezione del fault

(quindi il registro SP non ha subito modifiche), dopo aver effettuato la chiamata alla

sezione CheckInjection, vengono semplicemente ripristinati i valori originari dei registri

r28 ed r16 prima di eseguire l’istruzione target e l’istruzione successiva. Se invece il ciclo

di esecuzione corrente è quello relativo all’iniezione del fault, allora oltre a ripristinare i

valori originari dei registri r28 ed r16, viene caricato nel registro SP il valore ottenuto in

seguito all’iniezione del fault prima di eseguire l’istruzione target e subito dopo quella

successiva.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

51

Capitolo 3

AVR-INJECT Tool versione 2.0: la progettazione

In questo capitolo si descrive la progettazione della versione 2.0 del tool AVR-INJECT.

Pertanto sono mostrati alcuni use cases, un component diagram, un class diagram e

qualche sequence diagram. In particolare iniziamo evidenziando le differenze tra la

versione attuale e la versione precedente del tool.

3.1 AVR-INJECT Tool

Di seguito riportiamo il grafico che schematizza le fasi del tool mettendo in evidenza cosa

è stato aggiunto e che cosa è stato modificato.

Pre-Injection

Codice disassemblato (Golden Copy)

GC Trace GC Profile

Set-up esperimenti

Codice con inserzione (1...n)

Esecuzione

Profile (1..n)

Trace (1..n)

Analisi dei risultati

Input Input (Tabelle,Grafici...)

Figura 3.1: Fasi dell’AVR-INJECT Tool

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

52

Dalla figura 3.1 si nota che la fase di Set-up esperimenti è stata colorata di giallo per

indicare che ha subito modifiche rispetto alla versione precedente del tool mentre la fase di

Analisi dei risultati è stata colorata di verde per indicare che è stata implementata a

partire dalla versione corrente del tool.

Il tool, per il suo funzionamento, utilizza l’emulatore Avrora che permette di emulare una

rete di sensori senza filo i cui nodi sono dei microcontrollori AVR. E’ importante

evidenziare che i file di trace e di profile utilizzati o prodotti nelle varie fasi del tool sono

generati utilizzando gli strumenti messi a disposizione dall’emulatore Avrora.

Il tool permette l’esecuzione sia di singoli esperimenti che di studi di fault injection. In

particolare uno studio è un’insieme di esperimenti, il numero di tali esperimenti dipende

dagli intervalli di variazione del bit-flip e dell’istante di iniezione. Il tool prevede due

tipologie differenti di studio: studio step-by-step in cui l’utente deve specificare il valore

iniziale,quello finale ed il passo (step) sia per l’intervallo di variazione del bit-flip che per

quello dell’istante di iniezione; studio random in cui l’utente specifica il valore

iniziale,quello finale ed il passo (step) per un solo intervallo di variazione (bit-flip o istante

di iniezione) mentre per l’altro questi valori sono generati in modo casuale dal tool.

Durante la fase di Analisi dei risultati il tool oltre a confrontare il file di trace della

Golden Copy con quello degli esperimenti di fault injection interpreta i risultati

effettuando una classificazione. Descriviamo brevemente il meccanismo di classificazione

degli errori, in particolare le tipologie di errori considerate sono quattro: errori latenti ,

crash error, hang error ed errori da approfondire . Dal confronto dei file di trace si può

verificare una delle seguenti condizioni:

1. Nessuna differenza riscontrata: in questo caso per l’esperimento di fault

injection è stato individuato un errore latente.

2. Qualche differenza e presenza di cicli: in questo caso per l’esperimento di fault

injection è stato individuato un hang error.

3. Notevole differenza tra i cicli macchina eseguiti dalla golden copy e quelli

eseguiti dall’esperimento, indipendentemente dalle differenze: in questo caso

per l’esperimento di fault injection è stato individuato un crash error.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

53

4. Nessuna delle condizioni precedenti: in questo caso per l’esperimento di fault

injection è stato individuato un errore da approfondire.

3.2 Casi d’uso nel tool

Per chiarezza riportiamo di seguito il diagramma dei casi d’uso e poi per ognuno una

breve descrizione:

Nella figura 3.2 sono evidenziati i casi d’uso del tool con i relativi rapporti. Dal

diagramma si nota la presenza di un solo attore, l’utente, che è il solo che interagisce con il

sistema. Inoltre il caso d’uso relativo alla creazione di uno studio è stato scisso in due casi

d’uso distinti (step-by-step e random). Rispetto ai casi d’uso della versione precedente del

user

Delete experiment

Delete study

New step-by-stepstudy

New random study

Save project

Run project

Delete projectNew project

Open project

New experiment

View Results

Figura 3.2: Diagramma dei casi d’uso

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

54

tool, è stato inserito il caso d’uso per la visualizzazione dei risultati (View Results) ed è

stato modificato quello relativo all’esecuzione del progetto (Run project).

1. New project

E’ il caso d’uso più importante poiché da esso ha origine tutto il funzionamento

dell’AVR-INJECT tool. Infatti l’utente per poter impostare un esperimento o uno

studio per effettuare la fault injection deve innanzitutto creare un nuovo progetto

che include successivamente un certo numero di esperimenti o di studi. Per la

creazione del nuovo progetto all’utente è richiesto l’inserimento del nome

desiderato attraverso l’interfaccia GUI.

2. New experiment

Caso d’uso che consente l’inserimento di un nuovo esperimento, a cui l’utente può

assegnare un nome qualsiasi. E’ importante notare che questo caso d’uso richiede il

caso d’uso di creazione del progetto. In seguito alla creazione dell’esperimento,

nell’interfaccia GUI appare un nuovo pannello formato dai campi necessari a

contenere le informazioni relative all’esperimento di fault injection che si vuole

effettuare.

3. New step-by-step study

Avviene l’inserimento di un nuovo studio, a cui l’utente può assegnare un nome

qualsiasi. E’ importante notare che anche questo caso d’uso richiede il caso d’uso

di creazione del progetto. In seguito alla creazione dello studio, nell’interfaccia

GUI, appare un nuovo pannello formato dai campi necessari a contenere le

informazioni relative allo studio di fault injection che si vuole effettuare. I

parametri in questo tipo di studio sono tutti deterministici, in particolar modo si

ricorda che i valori del bit-flip e del ciclo d’iniezione sono ricavati attraverso uno

step impostato dall’utente.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

55

4. New random study

Avviene l’inserimento di un nuovo studio, a cui l’utente può assegnare un nome

qualsiasi. E’ importante notare che anche questo caso d’uso richiede il caso d’uso

di creazione del progetto. A differenza del precedente, in questo caso d’uso vi è

un’ulteriore radiobutton nel pannello dell’interfaccia GUI che consente all’utente di

scegliere quale tra il bit-flip e il numero di cicli deve essere generato in automatico

dal sistema.

5. Delete experiment

L’esperimento, dopo essere stato creato e/o avviato, può essere cancellato. Questo

caso d’uso permette all’utente di eliminare un esperimento all’interno di un

progetto. Per cancellare l’esperimento desiderato l’utente prima lo seleziona

all’interno dell’albero dei progetti, presente nell’interfaccia GUI, e poi dopo clicca

sull’apposito pulsante di cancellazione.

6. Delete study

A differenza dell’inserimento, non è più necessaria la distinzione tra studio step-by-

step e studio random. Il caso d’uso in questione prevede la rimozione di uno studio

indipendentemente dal tipo. Anche in questo caso per cancellare un particolare

studio l’utente prima lo seleziona all’interno dell’albero dei progetti, presente

nell’interfaccia GUI, e poi dopo clicca sull’apposito pulsante di cancellazione.

7. Delete project

L’utente può cancellare un progetto che in precedenza aveva realizzato per far

spazio a nuovi progetti con caratteristiche diverse. Anche in questo caso per

cancellare un particolare progetto l’utente prima lo seleziona all’interno dell’albero

dei progetti, presente nell’interfaccia GUI, e poi dopo clicca sull’apposito pulsante

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

56

di cancellazione. In questo caso la cancellazione di un progetto comporta anche la

cancellazione di tutti gli esperimenti e di tutti gli studi in esso contenuti.

8. Run project

E’ uno dei casi d’uso più interessanti nella fase di progettazione del tool. Con

l’ausilio di uno specifico pulsante, si avvia l’esecuzione del progetto selezionato

dall’utente. L’esecuzione consiste nella simulazione di tutti gli esperimenti e studi

presenti al suo interno. Questo caso d’uso è quello che ha subito delle modifiche

rispetto alla versione precedente del tool. Infatti nella versione attuale del tool

l’esecuzione di un progetto non si limita alla generazione di alcuni file per ogni

esperimento, ma realizza anche un’analisi approfondita di tali file. Inoltre,

terminata l’esecuzione, i risultati ottenuti sono visualizzati all’interno del tool

attraverso la creazione di appositi grafici.

9. Open project

Durante la realizzazione del tool, si è pensato che fosse opportuno recuperare

progetti salvati precedentemente per poterli modificare. Il tool gestisce quindi il

recupero di progetti purché essi siano stati precedentemente salvati all’interno del

sistema.

10. Save project

Quando l’utente decide di uscire dall’applicazione, se non è stato fatto un

salvataggio dell’albero dei progetti, tutto il lavoro andrà perso (problema della

persistenza dei dati). Quindi se l’utente desidera continuare la fault injection sui

progetti creati in una sessione successiva deve salvare l’albero dei progetti. A tale

scopo è presente nell’interfaccia GUI un apposito pulsante che serve a salvare le

informazioni dei progetti in un file xml.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

57

11. View Results

L’ultimo caso d’uso da considerare è la visualizzazione dei risultati. I risultati sono

disponibili solo se è stato già eseguito un progetto. I risultati sono riportati in forma

grafica (diagrammi a torta ed istogrammi) e sono associati ai particolari studi

attraverso un nodo Output nell’albero dei progetti.

3.3 Component diagram

Si è scelto appositamente di rappresentare prima il diagramma dei componenti del sistema

e poi il diagramma delle classi. Questo consente di avere principalmente una visione

globale del funzionamento del sistema mettendo a fuoco le dipendenze più evidenti. Nel

prossimo paragrafo si effettua un’analisi più approfondita ed accurata delle classi che

costituiscono il sistema. Per quanto riguarda il component diagram, sono stati individuati

quattro componenti principali (Figura 3.3): la GUI (Graphical User Interface),

l’esperimento, l’iniezione ed infine il parser XML. Di seguito descriviamo brevemente i

componenti:

GUI

Experiment

Injection XML Parser

Figura 3.3: Component diagram

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

58

• GUI

La GUI è stata implementata con l’ausilio delle librerie grafiche che java

mette a disposizione. Attraverso tale componente l’utente può utilizzare il tool

in maniera semplice ed intuitiva; sarà poi compito del tool fornire al sistema

le informazioni specificate dall’utente.

• Injection

Il componente Injection gestisce la vera e propria iniezione del fault. Esso si

occupa di trasformare il file della Golden Copy in un file dello stesso tipo

(ossia un file disassemblato con estensione .od) in cui è inserito anche la

porzione di codice che gestisce la fault injection.

• XML Parser

Questo componente analizza il file xml che il tool genera dinamicamente al

variare dei valori impostati dall’utente. In particolare, dopo che l’utente ha

specificato i valori e li ha confermati (i valori sono riferiti ai parametri che

caratterizzano gli esperimenti o gli studi che costituiscono un progetto), il tool

possiede in un file xml (trasparente all’utente) tutte le informazioni necessarie

per la simulazione. Quando l’utente vuole eseguire un progetto, il tool si serve

di un parser (ovvero analizzatore) che esamina il documento xml prodotto ed

estrae da esso le informazioni utili; queste informazioni sono poi inviate al

componente Experiment. In caso di salvataggio dei progetti, il contenuto del

file xml prodotto dal tool viene copiato interamente in un nuovo file xml; di

questo nuovo file xml l’utente sceglie il percorso di salvataggio ed il nome. Al

contrario, quando l’utente desidera caricare tutti i progetti contenuti in un file

xml, il tool effettua un’operazione inversa trasferendo il contenuto di tale file

nel file xml interno al tool (denominato input.xml) su cui opera il componente

XML Parser.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

59

• Experiment

Il componente Experiment è il componente principale del tool in quanto

gestisce i componenti Injection e XML Parser grazie ai quali può ottenere il

file definitivo che verrà utilizzato dall’emulatore Avrora. Tale componente è

stato progettato per realizzare singoli esperimenti, studi deterministici del tipo

step-by-step e studi aleatori. Inoltre rispetto alla versione precedente del tool,

questo componente ha anche il compito di analizzare, per ogni esperimento

eseguito, i file generati dall’emulatore Avrora e di visualizzare i risultati

ottenuti attraverso la creazione di appositi grafici.

3.4 Class diagram

Rispetto alla versione precedente, nella versione 2.0 dell’AVR-INJECT Tool sono state

introdotte sei nuove classi: AnalisiTrace.java, GenerateValChart.java, CreatePieChart.java,

CreateBarChart.java, CreateBarChartLat.java e MyCellRender.java. In questo paragrafo

descriviamo brevemente le classi che sono state ereditate dalla versione precedente del

tool, mentre analizziamo in modo più dettagliato le nuove classi introdotte.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

60

Nel diagramma di figura 3.4 le classi che hanno subito modifiche rilevanti rispetto alla

versione precedente del tool sono state colorate in giallo mentre quelle che sono state

introdotte nella nuova versione del tool sono state colorate di verde. Inoltre nel diagramma

non sono riportati gli attributi ed i metodi di ciascuna classe per una questione di spazio.

Main.java

E’ la classe principale dell’applicazione. Consente l’avvio del tool creando l’oggetto di

tipo ToolGUI che inizializza i componenti dell’interfaccia grafica.

ToolGUI.java

Realizza e gestisce tutti i componenti grafici necessari per l’impostazione ed esecuzione di

uno o più progetti.

OD

Riga

<<istantiate>><<istantiate>>

Iniezione

Esperimento

ParseXMLFile

«uses»

GenerateValChart

«uses»

CreatePieChart CreateBarChart CreateBarChartLat

«uses» «uses»

ToolGUI

«uses»

«uses»

Tree

«uses»

MyCellRender«uses»

Main

«uses»

ODFilter

«uses»

FilterJarFilterXml

«uses»«uses»

AnalisiTrace

«uses»

1

n<<istantiate>>

1

n

<<istantiate>>

1

n

<<is

tant

iate

>>

<<ist

antia

te>>

<<ist

antia

te>>

Figura 3.4: Class diagram

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

61

Esperimento.java

E’ la classe che si occupa di eseguire le operazioni richieste dalla classe ToolGUI per la

realizzazione della fault injection. Attraverso l’utilizzo di cicli for innestati, la classe

Esperimento prepara i file necessari per l’emulatore Avrora e, grazie ad appositi script,

imposta i comandi da eseguire per la simulazione. Inoltre rispetto alla versione precedente

del tool la classe Esperimento sfrutta le funzionalità di altre classi per analizzare i file

generati dall’emulatore Avrora e generare i grafici dei risultati.

Iniezione.java

E’ la classe che include il vero e proprio motore del tool. Infatti è in questa classe che si

costruisce passo dopo passo il file disassemblato modificato (il file ha estensione .od e

viene modificato in funzione dei parametri immessi dall’utente per l’iniezione del fault)

che serve all’emulatore Avrora per eseguire la simulazione.

ParseXMLFile.java

Per memorizzare i valori inseriti dall’utente, si è pensato di adoperare un file xml che viene

appositamente creato dal tool al suo avvio. La scelta di utilizzare questo tipo di file è nata

dalla semplicità di raccolta ed organizzazione delle informazioni poste su livelli diversi.

Pertanto è necessaria una classe che sia in grado di estrapolare dal file xml le informazioni

richieste conservando allo stesso tempo i loro rapporti di gerarchia.

OD.java

La classe OD (che prende il nome proprio dall’estensione del file che si vuole ottenere) ha

lo scopo di caricare il file .od di partenza (golden copy) e di cui l’utente è in possesso,

modificarlo aggiungendo blocchi di codice per la gestione dell’iniezione (in particolare i

blocchi di CheckInjection, Injection ed InstructionTarget), salvarlo e creare la directory

che conterrà tutti i file di output del tool.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

62

Riga.java

La classe Riga è stata creata per manipolare le righe del codice disassemblato. Mediante

questa classe il tool può estrarre una riga, può modificare la riga di codice corrispondente

al punto di iniezione sostituendo l’istruzione corrente con una chiamata al blocco relativo

all’injection (in particolare il blocco richiamato è InstructionTarget). Spesso il tool ricorre

ad un processo di tokenizzazione della riga: essa viene spezzettata in token i quali vengono

usati per determinati scopi (ad es. per il calcolo del Program Counter nei blocchi di codice

dell’injection).

Tree.java

Per una semplice navigazione tra i progetti, gli studi, gli esperimenti creati dall’utente si

ricorre ad una specifica classe: Tree. Da un punto di vista grafico essa consente di

visualizzare i progetti come tante cartelle che fanno capo ad una cartella radice denominata

Projects. Queste cartelle al loro interno contengono o soli esperimenti o soli studi o

entrambi. Da un punto di vista implementativo possiamo vedere una struttura ad albero

avente come radice il nodo Projects avente i progetti come nodi figli e gli esperimenti e/o

studi come nodi nipoti. Questa classe, rispetto alla versione precedente del tool, ha subito

delle modifiche importanti, in primo luogo è aumentata la profondità dell’albero

aggiungendo dei nodi figli ai nodi esperimento e ai nodi studio per contenere i grafici dei

risultati, ed in secondo luogo è cambiato l’aspetto grafico dei nodi esperimento e nodi

studio facilitando l’identificazione da parte dell’utente. In particolare, grazie all’utilizzo

della classe MyCellRender, è stato possibile associare immagini differenti alle tre tipologie

di nodi ossia agli esperimenti, agli studi step-by-step ed agli studi random, invece in

precedenza tutti i nodi avevano la stessa immagine e quindi risultava difficile da parte

dell’utente identificarli. Infine la classe Tree, per il corretto funzionamento del tool, crea

una corrispondenza biunivoca tra i nodi dell’albero e i nodi del file xml.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

63

ODFilter.java

E’ una classe ausiliaria per la ricerca e la selezione del file disassemblato (con estensione

.od) corrispondente alla golden copy di un’applicazione su cui effettuare la fault injection.

FilterXml.java

E’ una classe ausiliaria utilizzata per il salvataggio o l’apertura di progetti raccolti in un

file xml.

FilterJar.java

E’ una classe ausiliaria utilizzata per la ricerca del file con estensione .jar che permette

l’avvio dell’emulatore Avrora.

AnalisiTrace.java

La classe AnalisiTrace è stata creata per confrontare il file di trace dell’esperimento di

fault injection con quello della golden copy e classificare opportunamente il tipo di errore

individuato. L’output dell’analisi è un file testuale, chiamato Risultati.txt, che oltre al

risultato della classificazione contiene anche delle informazioni utili ricavate durante il

confronto; per chiarezza riportiamo di seguito il contenuto del file relativo ad un

esperimento di fault injection:

Si tratta di un hang error

Il TTH è: 14353

L'ampiezza del ciclo è: 27

La latenza del fault è di: 88

Il numero di disallineamenti è: 353431

Il numero di confronti è: 353443

Il numero di allineamenti a buon fine è: 0

Il numero di cicli identificati è maggiore di 2000

Tutte le problematiche affrontate in questa fase saranno presentate in modo dettagliato nel

paragrafo finale del capitolo.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

64

GenerateValChart.java

La classe GenerateValChart è stata creata per ottenere i valori in base ai quali costruire i

grafici dei risultati. E’ opportuno specificare che nel caso di un singolo esperimento non

viene generato nessun grafico ma sono riportate all’interno del tool solo le informazioni

contenute nel file Risultati.txt, la generazione dei grafici avviene solo in corrispondenza di

studi. Descriviamo brevemente il meccanismo per il calcolo dei valori con cui costruire i

grafici. La classe, tiene traccia del numero di errori di ciascuna categoria attraverso

l’utilizzo di appositi contatori che sono aggiornati al termine dell’esecuzione di ogni

esperimento di uno studio e subito dopo che è terminata la fase di analisi dei file di trace .

Quando poi sono stati eseguiti tutti gli esperimenti di uno studio, è possibile calcolare le

percentuali di occorrenza delle varie tipologie di errori e con questi valori realizzare i

grafici di interesse.

CreatePieChart.java

Questa classe, come si capisce già dal nome, ci permette di creare il grafico a torta che

mostra le percentuali di occorrenza delle quattro tipologie di errori nello studio di fault

injection. Per la realizzazione del grafico e la sua personalizzazione sono stati sfruttati i

metodi messi a disposizione dalla libreria grafica JFreeChart.

CreateBarChart.java

Questa classe, come si capisce già dal nome, ci permette di creare degli istogrammi dei

risultati di uno studio di fault injection. In particolare sono creati due tipi di istogrammi,

uno che mostra le percentuali di occorrenza delle quattro tipologie di errori al variare del

ciclo di iniezione e l’altro che mostra le percentuali di occorrenza delle quattro tipologie di

errori al variare del bit-flip. Per la realizzazione degli istogrammi e la loro

personalizzazione sono stati sfruttati i metodi messi a disposizione dalla libreria grafica

JFreeChart.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

65

CreateBarChartLat.java

Questa classe, come si capisce già dal nome, è simile alla classe precedente e ci permette

la realizzazione di un istogramma. La differenza sostanziale con la classe precedente sta

nel tipo di istogramma realizzato, infatti in questa classe viene creato l’istogramma della

latenza. In questo istogramma sono presi in considerazione solo gli errori di tipo crash e di

tipo hang e sono riportate le loro percentuali rispetto ai cicli di latenza riscontrati. E’ bene

ricordare che la latenza è definita come il numero di cicli che intercorrono dal momento in

cui si attiva l’iniezione (si verifica l’istante di iniezione) fino al momento in cui l’iniezione

agisce effettivamente sul sistema (provocando un crash error o un hang error). Anche in

questo caso, per la realizzazione dell’istogramma della latenza e la sua personalizzazione

sono stati sfruttati i metodi messi a disposizione dalla libreria grafica JFreeChart.

MyCellRender.java

Questa classe è stata realizzata per modificare a livello grafico l’albero dei progetti

presenti nel tool, in modo tale che l’utente possa distinguere tra esperimenti, studi step-by-

step e studi random, semplicemente guardando l’albero. In particolare questa classe

associa ai nodi esperimenti, ai nodi studio step-by-step ed ai nodi studio random delle

icone differenti.

3.5 Sequence diagram

Per brevità, in questo paragrafo, non si riportano i sequence diagram di tutti gli scenari del

tool ma solamente quelli di maggior interesse ai fini della sua comprensione e quelli che

hanno subito variazioni rispetto alla versione precedente del tool.

3.5.1 Sequence diagram n°1: nuovo esperimento

Si vuole illustrare lo scenario che realizza l’inserimento di un nuovo esperimento in un

progetto. In realtà questo scenario richiama un caso d’uso elencato precedentemente: New

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

66

experiment. Dallo schema dei casi d’uso si nota che la creazione di un nuovo esperimento

include il caso d’uso New project. Il sequence diagram rappresentato illustra lo scambio di

messaggi che avviene tra quattro entità importanti: l’utente (in qualità di attore),

l’interfaccia grafica del tool, il file xml generato ed utilizzato dal tool e il sistema operativo

che esegue alcuni comandi richiesti dal tool.

Utente :ToolGUI

crea nuovo progetto

inserisci nome progetto

progetto inserito con successo

:XML

aggiungi elemento project

crea nuovo esperimento

inserisci nome esperimento

aggiungi sottonodo experiment

esperimento inserito con successo

inserisci parametri config progetto

tool configurato con successo

seleziona path del file .od

:OS

richiesta elenco dei file .od del sistema

elenco dei file .od

visualizza elenco file

seleziona file desiderato

selezione del file desiderato

inizio attesa

simulazione della golden copy

emulazione

invio output emulazione

fine attesa

aggiungi sottonodo ad experiment

inserimento parametri

conferma valori inseriti

calcolo del valore "count"

esperimento configurato

richiesta valori inseriti

rilascio valori inseriti

visualizza valori inseriti

Figura 3.4: Sequence diagram: new experiment

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

67

Si osservi che i primi due messaggi inviati dall’utente ed il primo inviato dal tool servono

per la creazione di un progetto. Ad ogni avvio dell’applicazione non è possibile creare

nessun esperimento (o studio) senza un progetto esistente. Una funzione particolare svolta

dal sistema operativo riguarda l’emulazione della golden copy. Inoltre dopo che l’utente ha

inserito i parametri dell’esperimento, il tool ricava il valore di count in funzione della

locazione scelta.

3.5.2 Sequence diagram n°2: esecuzione di un progetto

Il sequence diagram che è oggetto di questo paragrafo richiama il caso d’uso Run project.

Si è scelto di analizzare questo caso sia perché è possibile comprendere, per sommi capi, il

funzionamento dell’AVR-INJECT tool da un punto di vista progettuale e sia perché ha

subito delle modifiche rispetto alla versione precedente del tool. In questo diagramma si

utilizzano le classi dell’applicazione e i messaggi scambiati corrispondono ad istanze di

nuovi oggetti e a chiamate di metodi con i rispettivi valori di ritorno (frecce in tratteggio).

Le entità chiamate in causa sono: l’utente, l’interfaccia grafica GUI associata alla classe

java ToolGUI, la classe Esperimento, la classe OD, la classe Riga, la classe ParseXMLFile,

la classe Iniezione, la classe Analisi Trace, la classe GenerateValChart, la classe

CreatePieChart, la classe CreateBarChart ed il sistema operativo. Osservando la figura 3.4,

che mostra il sequence diagram, si nota che il diagramma inizia con la creazione di un

esperimento questo perché è stato ipotizzato che il relativo progetto sia stato già creato in

precedenza.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

68

Figura 3.5: Sequence diagram: run project

Utente :ToolGUI :Esperimento :OD :Riga :ParseXMLFile :Iniezione

crea studio

studio creato

esegui progetto

simulazione avviata

<<create>>

init(pos)

<<create>>

<<create>>

<<create>>

albero dei nodi del file xml

<<create>>

checkinjection(ParseXMLFile.path,ParseXMLFile.ciclo[k],ParseXMLFile.tipo[k])

blocco stringhe checkinjection

injection(ParseXMLFile.maschera[k],ParseXMLFile.locazione[k],ParseXMLFile.tipo[k])

blocco stringhe injection

injection_core

blocco stringhe instruction target

modificaGC()

blocchi accodati

creaDir()

salva() :OS

script()

emulazione

file creati

:AnalisiTrace :GenerateValChart :CreatePieChart :CreateBarChart

analizza(pathGC,pathEsp,ciclo,loc)

tipo errore

aggiorna(ciclo,bit,pathEsp)

calPercTot(pathEsp)savePieChart(path,nome,dati)

calPercCiclo(pathEsp)

savaBarChart(path,nome,dati)

calPercBitFlip(pathEsp)saveBarChart(path,nome,dati)

fine esecuzionevisualizza grafici

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

69

Nel sequence diagram di figura 3.5 si è ipotizzato che non si siano verificati errori di tipo

crash o hang, nel caso in cui si fosse verificato almeno uno dei due allora avremmo

dovuto inserire nel diagramma la classe CreateBarChartLat. In questo caso la classe

Esperimento avrebbe invocato il metodo calPercLat() della classe GenerateValChart e

quest’ultima a sua volte avrebbe invocato il metodo saveBarLat() della classe

CreateBarChartLat per la creazione del grafico della latenza.

3.6 Problematiche affrontate

In questo paragrafo analizziamo in dettaglio le problematiche affrontate durante la fase di

progettazione e mostriamo le soluzioni adottate.

Il principale problema riscontrato è relativo alla fase di analisi dei file di trace, necessaria

alla classificazione degli errori, ed è dovuto all’elevata dimensione dei file di trace

generati dall’emulatore Avrora (nell’ordine delle centinaia di MB per una simulazione di

due secondi). Per la classificazione degli errori, c’è la necessità di confrontare, istruzione

per istruzione, il file di trace della golden copy con quello dell’esperimento di fault

injection eseguito (fase di analisi), quindi un’elevata dimensione di questi file

provocherebbe un tempo di esecuzione eccessivo per la fase di analisi. La soluzione

adottata è quella di tagliare i file di trace conservando tutte le informazioni a partire dal

punto di iniezione in poi; il taglio effettuato non crea problemi in quanto prima del punto

di iniezione il trace della golden copy coincide con quello dell’esperimento (ovviamente

sono escluse dal confronto le istruzioni introdotte per effettuare la fault injection). Per il

taglio dei file di trace, abbiamo deciso di utilizzare i file ad accesso casuale di java

(sfruttando la classe RandomAccessFile) per posizionarci in modo diretto sul punto di

iniezione; tuttavia il metodo seek() utilizzato, richiede di specificare di quanto spostare il

puntatore al file rispetto all’inizio del file, in termini di numero di byte. Per ricavare

l’offset (numero di byte) abbiamo creato un apposito script, che memorizza in un file tutte

le occorrenze della locazione di iniezione (ricavate dal file di trace) mostrando per ognuna

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

70

di essa il relativo offset; per chiarezza riportiamo di seguito lo script creato:

source /etc/bash.bashrc

cat esp_Trace.txt | grep -b 216C: > Outgrep.txt

cat TraceBlink.txt | grep -b 216C: > Outgrepgc.txt

exit

Nell’esempio mostrato la locazione in cui iniettare il fault è 216C. Tra tutti i valori

disponibili, il valore di offset da utilizzare viene scelto in base al ciclo di iniezione

specificato dall’utente, ad esempio se l’utente scegliesse il secondo ciclo per l’iniezione,

allora verrebbe scelto il valore di offset relativo alla seconda occorrenza della locazione in

cui si vuole iniettare il fault. Con questo meccanismo, le dimensioni dei file di trace si

riducono mediamente di un fattore 100 (ad esempio passando da qualche centinaia di MB

a qualche MB).

Un altro problema affrontato è stato quello di escludere, dal confronto eseguito nella fase

di analisi, le istruzioni introdotte per la fault injection; vi è la necessità di escludere queste

istruzioni, in quanto, se fossero considerate verrebbero sempre riscontrate delle differenze

(anche nel caso in cui non ci sono) tra il file di trace dell’esperimento di fault injection e

quello della golden copy. E’ importante ricordare che la modifica al file disassemblato per

la realizzazione della fault injection, comporta l’inserimento di blocchi di istruzioni in

coda al file. Quindi per inserire questi blocchi di istruzione e calcolare automaticamente le

locazioni di memoria occupate, il tool calcola qual è l’ultima locazione di memoria

occupata dalle istruzioni del file disassemblato. Questa informazione ci permette di

escludere dal confronto (effettuato nella fase di analisi) tutte le istruzioni che hanno un

indirizzo di memoria superiore all’ultimo; in questo modo non sono considerate le

istruzioni relative alle sezioni di: CheckInjection, Injection ed InstructionTarget.

Riportiamo di seguito la porzione di codice che ci permette di effettuare l’esclusione:

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

71

if (indesp.equals(indfault)||(indesp.compareTo(la stline)>=0))

{

rigaesp=fesp.readLine();

posesp=fesp.getFilePointer();

tokenesp=tokenizer(rigaesp," ");

indesp=(String)tokenesp.elementAt(2);

indesp=indesp.substring(0, indesp.length()-1);

while ((indesp.compareTo(lastline)>=0)&&(posesp<finesp-40 0))

{

rigaesp=fesp.readLine();

posesp=fesp.getFilePointer();

tokenesp=tokenizer(rigaesp," ");

indesp=(String)tokenesp.elementAt(2);

indesp=indesp.substring(0, indesp.length()-1);

}

}

Nella porzione di codice indfault indica la locazione in cui si vuole iniettare il fault, indesp

rappresenta la locazione corrente ricavata dal file di trace e finesp rappresenta la fine del

file di trace. E’ importante notare che per ricavare le locazioni di memoria su cui effettuare

il confronto viene utilizzata la procedura tokenizer.

Infine un ulteriore problema affrontato è quello dell’individuazione di cicli di istruzioni

durante la fase di analisi, è importante individuare questi cicli in quanto il loro

manifestarsi è uno dei sintomi della presenza di un hang error. Il problema in questo

caso è l’individuazione bel blocco di istruzioni che si ripete in quanto non si conosce

neanche la sua lunghezza; per questo problema è stato implementata un’apposita

procedura. Questa procedura utilizza i file ad accesso casuale di java (sfruttando la classe

RandomAccessFile) per lo spostamento all’interno del file; infatti quando è individuato un

ciclo vengono saltate tutte le sue istruzioni. Per individuare un ciclo, visto che non si

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

72

conosce la lunghezza, viene ispezionato il file di trace considerando 50 istruzioni per volta

che sono memorizzate all’interno di un array; il meccanismo è di confrontare un’istruzione

dell’array con le altre finché non viene riscontrata un’uguaglianza a quel punto si

confrontano le due istruzioni successive (rispetto a quelle riscontrate uguali) e così via

finché non si incontra una differenza (vuol dire che il ciclo è terminato). A questo punto si

ripete il procedimento partendo dall’istruzione successiva rispetto a quella che rappresenta

l’ultima istruzione del ciclo individuato. Riportiamo di seguito il codice della procedura:

poscorrente=posfirstdiff;

while ((poscorrente<finesp-400-2000)&&(numCicli<2 000))

{

fesp.seek(poscorrente);

for (int i=0; i<50; i++)

{

rigaesp=fesp.readLine();

posesp=fesp.getFilePointer();

tokenesp=tokenizer(rigaesp," ");

indesp=(String)tokenesp.elementAt(2);

indesp=indesp.substring(0, indesp.length()-1);

cEsp=(String)tokenesp.elementAt(1);

arrayInd[i]=indesp;

arrayPos[i]=posesp;

arrayCicli[i]=cEsp;

}

poscorrente=fesp.getFilePointer();

for (int i=0; i<50; i++)

{

int j=i+1;

while ((j<50))

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

73

{

if (arrayInd[i].equals(arrayInd[j]))

{

lunghezza=j-i;

l=i+1;

trovCiclo=true;

fesp.seek(arrayPos[j]);

while ((l<lunghezza+i+1)&&(trovCiclo))

{

rigaesp=fesp.readLine();

posesp=fesp.ge tFilePointer();

tokenesp=tokenizer(rigaesp," ");

indesp=(String)tokenesp.elementAt(2);

indesp= indesp.substring(0,indesp.length()-1);

if (!(arrayInd[l].equals(indesp)))

trovCiclo=false;

l++;

}

if (trovCiclo)

{

numCicli++;

if (numCicli==1)

espCiclo=arrayCicli[i];

j=j+lunghezza;

}

}

j++;

}

if (trovCiclo)

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

74

i=i+(2*lunghezza);

}

E’ interessante notare che la procedura termina o quando si raggiunge la fine del file di

trace oppure quando sono individuati 2000 cicli (che è un valore sufficientemente

rilevante per la presenza di un hang error). Inoltre è stato scelto, come limite alla

lunghezza del ciclo, un valore pari a 50 in quanto si è notato che la lunghezza media non

supera il valore 30. Infine vengono utilizzati tre array che memorizzano: le locazioni di

memoria che sono analizzate (arrayInd) , le posizioni del puntatore al file di trace relative

alle varie locazioni (arrayPos) ed il valore dei cicli macchina eseguiti relativamente alle

varie locazioni (arrayCicli, queste ultime informazioni sono necessarie per il calcolo della

latenza).

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

75

Capitolo 4

AVR-INJECT Tool: esecuzione di un progetto

In questo capitolo si vuole mostrare al lettore, attraverso l’ausilio di alcune schermate,

come configurare ed utilizzare l’AVR-INJECT Tool per l’esecuzione di un progetto. In

particolare focalizzeremo la nostra attenzione sull’esecuzione di un progetto contenente

uno studio step-by-step in quanto questa tipologia di studio è stata utilizzata per realizzare

la campagna di fault injection descritta nel capitolo successivo.

4.1 Creazione e configurazione di un progetto

All’avvio del tool, la prima schermata che compare all’utente è la seguente:

Figura 4.1: Avvio del tool

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

76

L’utente per poter iniziare una fault injection deve necessariamente creare un nuovo

progetto (figura 4.2). Supponiamo che l’utente decida di inserire uno studio step-by-step

nel progetto (figura 4.3). E’ bene ricordare che uno studio è un insieme di esperimenti e

che nel caso di studio step-by-step l’utente deve specificare gli intervalli di variazione del

bit-flip e dell’istante di iniezione. Una volta generato un progetto ed aver scelto di

effettuare uno studio, occorre configurare il progetto indicando al tool i parametri necessari

per la fault injection quali la piattaforma del microcontrollore, il tempo di simulazione,

l’archivio jar per eseguire l’emulatore Avrora e il percorso della cartella in cui si salvano

tutti i risultati relativi al progetto configurato. Nella figura 4.4 sono illustrati i campi da

settare i cui valori sono stati inseriti a scopo esemplificativo: si noti che ad ogni operazione

eseguita, il tool rilascia un messaggio di log nella finestra in basso alla schermata (Log

messages).

Figura 4.2: Creazione nuovo progetto

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

77

E’ importante precisare che prima di impostare qualsiasi esperimento o studio (step-by-

step o random) è fondamentale, per un corretto funzionamento del tool, la configurazione

Figura 4.3: Creazione nuovo studio step-by-step

Figura 4.4: Configurazione progetto

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

78

del progetto padre che li contiene. Infatti per impostare un esperimento o uno studio, il tool

utilizza i parametri scelti durante la configurazione del progetto.

4.2 Configurazione di uno studio step-by-step

Seguendo l’esempio del paragrafo precedente, supponiamo dunque che nel progetto

l’utente abbia deciso di eseguire uno studio di fault injection al variare del bit-flip e

dell’istante di iniezione. Occorre configurarlo, impostando il tipo di guasto da simulare

(tipo codice, memoria, nei registri Program Counter, Status Register e Stack Pointer),

l’intervallo di variazione del bit da flippare e l’intervallo di variazione dell’istante di

iniezione (dato che un’istruzione può essere eseguita più volte indica in quale di queste

iniettare il fault), il percorso del file disassemblato (con estensione .od) relativo

all’applicazione in cui si vuole effettuare la fault injection ed infine la locazione (o le

locazioni) in cui iniettare il fault.

La prima cosa da fare è selezionare il file .od di riferimento per la fault injection. Per il

particolare esempio abbiamo utilizzato il file BlinkAppCNO.od (figura 4.5).

Figura 4.5: Selezione file disassemblato

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

79

In seguito alla conferma del file scelto, il tool mette in attesa l’utente mascherando in

effetti un’operazione molto importante: il calcolo del valore count (numero di volte che

l’istruzione target scelta viene eseguita). In altre parole, quando l’utente viene messo in

attesa (attraverso la finestra di popup Waiting the task visualizzata in figura 4.6), il tool

provvede ad effettuare uno ‘studio del sistema target’ (fase di pre-injection), operazione

preliminare che serve a generare i file di trace e di profile della Golden Copy. Questo passo

è molto importante perché consente al tool di ricavare per ogni locazione inserita

dall’utente, il numero di esecuzioni della corrispondente istruzione (count number). A

questo punto è possibile capire l’importanza della configurazione iniziale del progetto:

infatti per ricavare il valore del count number, il tool esegue un comando che invoca

l’emulatore Avrora, per generare il file di profile, e che utilizza come parametri la

piattaforma ed il percorso del file jar di Avrora specificati durante la configurazione del

progetto.

Dopo che l’utente ha scelto il file disassemblato (nell’esempio BlinkAppCNO.od) deve

indicare il punto di iniezione. In uno studio è possibile inserire più di una locazione

Figura 4.6: Waiting the task

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

80

(injection point) purché siano separate dal carattere di virgola ‘,’. Per inserire le locazioni

di iniezione ci sono tre possibilità: l’utente può immettere direttamente le locazioni (in

forma esadecimale e separate dalla virgola) oppure può selezionarle da una lista (creata

appositamente dal tool al caricamento del file disassemblato – figura 4.7) oppure lascia il

campo vuoto delegando il tool nella scelta delle locazioni.

Per default il tipo di guasto da simulare è Code; nell’esempio noi lo impostiamo su

Memory così da simulare guasti nelle celle di memoria. Per default il valore iniziale, quello

finale e lo step per l’intervallo di variazione del bit-flip sono impostati ad 1; mentre il

valore iniziale, quello finale e lo step per l’intervallo di variazione che permette il calcolo

degli istanti di iniezione sono impostati rispettivamente a 0, 0.1 e 1. Per l’esempio, che è a

scopo illustrativo, abbiamo deciso di far variare il bit da flippare da 1 ad 8 con passo 1

(figura 4.8) mentre abbiamo deciso di effettuare l’iniezione alla prima esecuzione delle

istruzioni associate alle locazioni scelte (figura 4.9). In particolare per l’iniezione sono

state scelte due differenti locazioni 1102 e 145a (figura 4.10).

Figura 4.7: Selezione della locazione

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

81

Impostati tutti i valori necessari, si può confermare la configurazione dello studio (figura

4.11). In questo caso il tool mediante la finestra Log messages riporta un resoconto dei

parametri inseriti. Inoltre il tool provvede ad informare l’utente sul numero di esecuzioni

delle istruzioni coinvolte nella fault injection (count number).

Figura 4.8: Impostazione dei valori per il bit-flip

Figura 4.9: Impostazione dei valori per l’istante di iniezione

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

82

Figura 4.10: Scelta delle locazioni

Figura 4.11: Conferma dello studio step-by-step

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

83

4.3 Esecuzione di un progetto e visualizzazione dei risultati

In questo paragrafo descriviamo come avviene l’esecuzione di un progetto e come sono

visualizzati i risultati all’interno del tool, come progetto scegliamo quello descritto nei

paragrafi precedenti.

Le figure sovrastanti illustrano rispettivamente l’icona associata all’evento di esecuzione di

un progetto e il messaggio rilasciato dal tool quando la simulazione viene avviata. A

questo punto l’utente resterà in attesa dei risultati prodotti dall’AVR-INJECT Tool. In

particolare mostriamo di seguito il messaggio mostrato dal tool quando l’esecuzione è

terminata.

Quando la simulazione è conclusa c’è la possibilità di visualizzare i risultati all’interno del

tool attraverso l’albero di navigazione dei progetti. Riportiamo di seguito i risultati

ottenuti dall’esecuzione del progetto di esempio.

Figura 4.12: Esecuzione di un progetto

Figura 4.13: Fine esecuzione

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

84

In particolare si vede come la presenza di un grafico a torta che riporta le percentuali di

occorrenza delle tipologie di errori riscontrati, due istogrammi che riportano le percentuali

Figura 4.14: Risultati parte uno

Figura 4.15: Risultati parte due

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

85

di occorrenza degli errori al variare del bit-flip e del ciclo (istante) di iniezione. Inoltre nel

caso in cui sono rilevati errori di tipo crash o di tipo hang il tool genera anche il grafico

che riporta le percentuali di occorrenza di questi errori in funzione dei cicli di latenza

riscontrati (in particolare nel grafico di figura 4.15 si mostra la latenza riscontrata per gli

errori di tipo hang).

4.4 Files generati dal tool

L’utente, all’atto della configurazione di un progetto, indica il percorso della cartella che

contiene i file creati dal tool. L’organizzazione delle cartelle è la seguente: il tool crea

innanzitutto una cartella chiamata Project x (la x indica il nome scelto dall’utente per un

particolare progetto); l’applicazione poi crea all’interno di suddetta cartella, un numero di

cartelle pari al numero di studi ed esperimenti inclusi in un progetto. Inoltre i nomi di

queste cartelle riportano il tipo ed il nome dell’esperimento.

Nella figura 4.16 viene mostrato il contenuto della cartella che contiene i risultati dello

studio eseguito.

Figura 4.16: File contenuti nella cartella del progetto eseguito

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

86

Dalla figura 4.16 si nota la presenza dei grafici generati dal tool e mostrati in precedenza,

ed una cartella per ognuna delle locazioni specificate. Riportiamo di seguito un grafico che

contiene tutti i file generati dal tool per un particolare esperimento di fault injection (in

particolare quello relativo alla locazione 145a con bit flip 5 e ciclo di iniezione pari ad 1).

Descriviamo di seguito brevemente i vari file generati dal tool.

4.4.1 File Esp_*.od

Si tratta di un codice disassemblato in cui a differenza di quello della Golden Copy vi sono

ulteriori blocchi di codice per la gestione della fault injection. In particolare sono presenti i

blocchi di: CheckInjection, Injection ed InstructionTarget come previsto dalla tecnica di

fault injection utilizzata dal tool (tecnica di iniezione a livello assembly basata

sull’iniezione di codice).

Figura 4.17: File contenuti nella cartella di un particolare esperimento di fault injection

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

87

4.4.2 File esp_avrora.txt

E’ il primo file generato dall’emulatore Avrora. In esso vi è la simulazione che descrive gli

eventi, gli istanti temporali e i nodi associati ad uno degli eventi.

Nella particolare applicazione di prova (Blink) un evento rappresenta la transizione dello

stato di uno dei tre led del sensore (on -> off e viceversa).

4.4.3 File esp_Memory.txt

In certi contesti può risultare molto interessante osservare il comportamento della memoria

di un programma. Ad esempio sarebbe utile conoscere se un programma alloca locazioni di

memoria riservate cioè non utilizzabili oppure se si verifica un problema di overflow nello

stack di memoria. Per tale motivo, si utilizza uno dei monitor messi a disposizione

dall’emulatore Avrora: il memory monitor. Esso consente ai programmatori di esaminare il

comportamento della memoria di un programma e creare un report in cui si riportano le

locazioni di memoria con le rispettive percentuali di utilizzo in lettura e scrittura. Tale

report è anche utile per verificare eventuali accessi in memoria non consentiti.

4.4.4 Files esp_Profile.txt e esp_Calls.txt

I files esp_Profile.txt ed esp_Calls.txt sono generati dall’emulatore Avrora impostando il

parametro monitor rispettivamente a profile e calls.

Il primo monitor (profile) registra il numero di esecuzioni di ogni istruzione in un

programma. Il secondo monitor (calls) gestito dal simulatore riporta tutte le chiamate e le

interruzioni eseguite dal programma.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

88

4.4.5 File Trace.txt

Inizialmente all’interno della cartella è contenuto il file esp_Trace.txt ottenuto

dall’emulatore Avrora impostando il parametro monitor a trace; questo file riporta tutte le

istruzioni coinvolte nell’esecuzione dell’applicazione. Il file Trace.txt è ottenuto dal file

esp_Trace.txt scartando tutte le istruzioni che precedono il punto di iniezione; quando la

creazione del file è terminata il file esp_Trace.txt è cancellato allo scopo di limitare

l’occupazione di memoria necessaria a contenere le informazioni relative alla fault

injection realizzata.

4.4.6 File avr.sh

Il file avr.sh è uno script che raccoglie una serie di comandi interpretati dalla shell testuale

Bash. Attraverso la Bash l’utente è in grado di comunicare con il sistema operativo.

Attraverso questo script è invocato l’emulatore Avrora impostando opportunamente i

monitor in modo da generare i file descritti in precedenza. Il tool, nel corso

dell’esecuzione di un esperimento, crea ogni volta un nuovo script bash che viene salvato

insieme agli altri file di output.

4.4.7 File avrGrep.sh

Il file avrGrep.sh è uno script che raccoglie una serie di comandi interpretati dalla shell

testuale Bash. Questo script ci permette di conoscere la posizione di ogni occorrenza

dell’istruzione target (istruzione in cui si vuole iniettare il fault) all’interno del file

esp_Trace.txt espressa in termini di numero di byte. Inoltre lo script memorizza queste

informazioni all’interno del file Outgrep.txt.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

89

4.4.8 File Risultati.txt

Questo file contiene in forma testuale i risultati dell’analisi effettuata tra il file di trace

della Golden Copy e quello del particolare esperimento di fault injection. In particolare

oltre a riportare il tipo di errore riscontrato (hang, crash, errori latenti o errori da

approfondire) riporta le informazioni relative al numero di confronti effettuati, al numero

di differenze riscontrate ed il valore di latenza individuato.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

90

Capitolo 5

Utilizzo del tool: analisi comparativa tra TinyOS e Mantis

La campagna di fault injection realizzata ha lo scopo di mostrare le potenzialità dell’AVR-

INJECT tool confrontando il comportamento di due sistemi operativi, per reti di sensori

senza filo, molto diffusi: TinyOS e Mantis OS(MOS).

In particolare per il confronto sono state utilizzate due applicazioni target simili,

l'applicazione Blink per TinyOS e l'applicazione blink_led per MOS; inoltre per dimostrare

la generalità del tool sono stati effettuati alcuni esperimenti di fault injection anche

nell’applicazione sense_and_forward che è un’applicazione tipica per le reti di sensori

senza filo.

L’utilizzo dell'AVR-INJECT tool ci ha permesso di ottenere i risultati:

• più velocemente (mediamente un esperimento realizzato a mano richiede circa

dieci minuti mentre con il tool sono necessari circa cinque minuti).

• in modo più affidabile (sono esclusi possibili errori umani).

• in modo più preciso (in quanto il file di trace dell'esperimento è confrontato

istruzione per istruzione con quello della golden copy).

• in modo più intuitivo (i risultati ottenuti sono visualizzati graficamente).

Gli outcome, ovvero i risultati ottenuti, sono stati suddivisi in quattro categorie:

- Errori latenti : sono gli errori che non influenzano l'esecuzione del sistema

durante l'intervallo di tempo dell'esperimento.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

91

- Crash errors : sono conseguenze di un guasto che portano il sistema in uno

stato di malfunzionamento interrompendo la sua normale

esecuzione.

- Hang errors : sono errori che non provocano un arresto quasi istantaneo

del sistema ma lo conducono in uno stato di loop: un blocco

di istruzioni successive al punto di iniezione viene ripetuto

n volte provocando una situazione di stallo.

- Errori da approfondire : sono errori temporanei che portano il sistema a

divergere, in più punti e per piccoli intervalli di

tempo, dalla sua normale esecuzione per poi

successivamente riallinearsi ad essa.

L’obiettivo della campagna di fault injection realizzata è quello di effettuare un’analisi

comparativa tra Mantis OS e TinyOS rispetto al loro comportamento in presenza di guasti.

In particolare vogliamo valutare la robustezza ai guasti (in generale la robustezza di un

sistema è la misura in cui il sistema si comporta in modo ragionevole in situazioni

impreviste ossia non contemplate dalle specifiche; nel nostro caso le situazioni impreviste

riguardano la presenza di guasti) dei due sistemi operativi. Ad esempio, se un sistema ha

la percentuale maggiore di errori latenti possiamo dire in un certo senso che è più robusto

anche se tali errori potrebbero comunque attivarsi successivamente. In modo analogo, un

sistema che presenta una percentuale maggiore di errori di tipo crash è in un certo senso

più “safe” infatti visto che ne viene bloccata l’esecuzione si ha una probabilità minore che

si verifichino danni catastrofici. Invece un sistema che presenta la percentuale maggiore di

errori di tipo hang oppure di errori da approfondire comporta un problema di spreco di

risorse, infatti il carico elaborativo superiore comporta nel nodo sensore un consumo

energetico superiore.

Le metriche utilizzate per la valutazione sono le percentuali di occorrenza delle tipologie di

errore descritte in precedenza e la distribuzione di latenza ottenuta nei casi di errori di tipo

crash ed hang. La latenza è definita come il numero di cicli macchina che intercorrono dal

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

92

momento in cui si attiva l’iniezione (si verifica l’istante di iniezione) fino al momento in

cui l’iniezione agisce effettivamente sul sistema (provocando un crash error o un hang

error).

Attraverso l'AVR-INJECT Tool è possibile iniettare guasti nel codice, in memoria e nei

registri del processore (PC, SP, SR) quindi la campagna di fault injection realizzata è stata

programmata in modo tale da coprire tutte queste tipologie di iniezione. In particolare per

ogni tipologia di iniezione sono stati eseguiti alcuni studi step-by-step nei quali la

locazione in cui effettuare l’injection è scelta in modo casuale mentre sono fissati gli

intervalli di variazione del ciclo e del bit flip. Per il bit flip l’intervallo di variazione è

unico, parte dal valore 1 ed arriva al valore 8 con passo 1. Per il ciclo (istante di iniezione)

l’intervallo di variazione standard parte da 0 ed arriva ad 1 con passo 0.2 (è bene ricordare

che questi valori sono normalizzati quindi al valore 1 corrisponde l’ultima esecuzione della

particolare locazione considerata). E’ importante precisare che il numero di esperimenti di

fault injection realizzati nelle varie locazioni non è sempre lo stesso; questo perché il

numero dei valori generati dall’intervallo di variazione del ciclo varia in funzione del count

associato alla locazione scelta (il count indica quante volte la locazione viene richiamata).

Riportiamo di seguito una tabella che riassume il numero di esperimenti di fault injection

eseguiti suddivisi per tipologia di iniezione:

Codice Memoria PC SP SR

Mantis OS 432 304 432 280 304

TinyOS 312 328 280 296 304

Nei paragrafi successivi analizziamo in modo dettagliato i risultati ottenuti, sia per Mantis

che per TinyOS.

5.1 Fault injection in Mantis OS

Per analizzare in modo più dettagliato i risultati ottenuti, li presentiamo prima suddivisi

Tabella 5.1: Esperimenti di fault injection suddivisi per tipologia di iniezione

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

93

per tipologia di iniezione e poi successivamente in una visione di insieme.

5.1.1 Code Error Injection

Il grafico a torta sottostante mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel codice

dell’applicazione blink_led. Sono stati realizzati 432 esperimenti di fault injection raccolti

in 12 studi step-by-step.

Su 432 esperimenti di fault injection effettuati nel codice dell’applicazione:

• il 33,3% degli esperimenti ha provato la robustezza dell’applicazione blink_led.

L’iniezione del guasto non ha influenzato il suo normale funzionamento.

• il 2,1% degli esperimenti ha riportato un caso di Hang Error .

• l’1,4% degli esperimenti ha riportato un caso di Crash Error.

• il 63,2% degli esperimenti ha riportato un caso di errore che merita ulteriori

approfondimenti.

Figura 5.1: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel codice

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

94

Per brevità nella tabella seguente si riportano solo le locazioni ottenute dal tool, il numero

di esperimenti ad essi associati, le procedure e i tipi di errore riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

12e0 hardware_id_init 6 0 0 10

1f0 start 0 5 0 3

2232 mica2_battery_init 0 0 0 8

236 mos_led_init 0 0 0 8

284 mos_led_off 0 0 0 8

3116 __vector_22 0 0 8 0

3a2 plat_init 0 1 0 7

47cc mos_thread_wakeup_noints 0 0 32 64

4be0 mos_thread_sleep 0 0 88 8

4d70 mos_mem_alloc 0 0 8 64

4de6 mos_mem_free 3 0 0 5

51a2 mos_tlist_ordadd 0 0 8 88

Dalla tabella si nota che per alcune locazioni sono stati effettuati solo 8 esperimenti di

fault injection questo vuol dire che le relative istruzioni sono eseguite una sola volta e

quindi l’istante di iniezione (ciclo) è sempre lo stesso; di conseguenza gli esperimenti sono

eseguiti solo al variare del bit-flip da 1 ad 8 con passo 1. Invece per altre locazioni sono

stati effettuati un numero di esperimenti di fault injection multipli di 8, questo vuol dire

che gli esperimenti sono eseguiti variando sia il bit-flip che il ciclo d’iniezione.

Inoltre guardando la tabella possiamo affermare che in generale, fissata la locazione, la

variazione della tipologia di errore rispetto alla variazione del bit-flip e del ciclo di

iniezione è bassa. E’ interessante quindi analizzare più in dettaglio un caso in cui c’è una

Tabella 5.2: Parametri utilizzati per la campagna di fault injection nel codice e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

95

variabilità rispetto al bit-flip e all’istante di iniezione. Riportiamo di seguito una porzione

di codice della procedura hardware_id_init che contiene la locazione 12e0 :

12d8: 0e 94 fe 08 call 0x11fc ; 0x11fc <read_byte > 12dc: 89 93 st Y+, r24 12de: 82 e0 ldi r24, 0x02 ; 2 12e0: c9 36 cpi r28, 0x69 ; 105 12e2: d8 07 cpc r29, r24 12e4: c9 f7 brne .-14 ; 0x12d8 <h ardware_id_init+0x96>

In particolare in seguito all’iniezione effettuata viene modificato uno dei bit del registro

r28, quindi il contenuto di tale registro viene confrontato con un valore immediato.

L’istruzione successiva anche se non utilizzata direttamente il valore del registro r28, che

è stato modificato, viene influenzata indirettamente dal risultato dell’istruzione precedente

(l’esecuzione dell’istruzione target modifica alcuni flag del registro SR). La presenza di

errori di tipo Hang, per gli esperimenti di fault injection realizzati in questa locazione, è

dovuta all’istruzione di salto condizionato all’indietro (brne -14) nelle immediate

vicinanze dell’istruzione target (istruzione in cui è stato iniettato il fault); infatti

l’iniezione effettuata può in alcuni casi modificare la condizione di salto in modo da

generare un loop (essendo un salto condizionato relativo con spiazzamento negativo se la

condizione di salto è sempre verificata allora vengono eseguite ripetutamente le stesse

istruzioni).

Un altro studio di fault injection che è interessante approfondire è quello relativo alla

locazione 4be0 in cui si sono riscontrati ben 88 casi di errori latenti. Riportiamo di seguito

una porzione di codice della procedura mos_thread_sleep che contiene la locazione 4be0:

4bd8: 0e 94 b4 28 call 0x5168; 0x5168 <mos_tlist_ordadd>

4bdc: 80 91 71 03 lds r24, 0x0371 4be0: 6d 2d mov r22, r13 4be2: 99 27 eor r25, r25 4be4: 0e 94 c6 23 call 0x478c; 0x478c <mos_thread_wakeup_noints> 4be8: 1f 91 pop r17 4bea: 0f 91 pop r16 4bec: ff 90 pop r15 4bee: ef 90 pop r14 4bf0: df 90 pop r13 4bf2: 08 95 ret

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

96

Dal codice si capisce che i vari esperimenti di fault injection realizzati modificano uno dei

bit del registro r22. In questo caso l’elevato numero di errori latenti riscontrati è dovuto al

fatto che nelle immediate vicinanze dell’istruzione in cui si è iniettato il fault non viene

utilizzato il valore del registro r22.

Nel grafico successivo (istogramma) si riportano le percentuali degli errori di Crash ed

Hang che si sono verificati nel corso dei 432 esperimenti in funzione dei cicli di latenza

riscontrati.

Dall’istogramma si possono trarre delle conclusioni interessanti. In primo luogo la

maggior parte degli errori (60%) ha una latenza che non supera i 90 cicli (essendo

l’ATmel128L un processore RISC corrispondono a circa 90 istruzioni). Inoltre dalla

tabella 5.2 notiamo che su 432 esperimenti si sono verificati 9 casi di errori di tipo Hang

(tre dei quali nella locazione 4de6 con latenza di 90 cicli ed i restanti sei nella locazione

12e0 con latenza superiore a 160 cicli in particolare il valore massimo di latenza

riscontrato è di 30850 cicli macchina) e 6 casi di errori di tipo Crash tutti con una latenza

che non supera i 70 cicli. In base ai risultati ottenuti, possiamo affermare che

relativamente alla fault injection realizzata nel codice la latenza degli errori di tipo Hang è

maggiore di quella degli errori di tipo Crash.

Figura 5.2: Latenza relativa all’iniezione nel codice

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

97

5.1.2 Memory Error Injection

Il grafico a torta sottostante mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti in memoria. Sono stati

realizzati 304 esperimenti di fault injection raccolti in 18 studi step-by-step. Come si nota

dal grafico per questa tipologia di iniezione si ha una prevalenza di errori latenti con una

percentuale del 55,5%.

Bisogna notare che in questo caso, rispetto all’iniezione nel codice, sono aumentate le

percentuali di Crash Error e di errori latenti a discapito della percentuale degli errori da

approfondire, mentre sono completamente assenti gli errori di tipo Hang (presumibilmente

questo è dovuto al fatto che durante gli esperimenti di fault injection eseguiti non sono

state modificate le condizioni di terminazione dei cicli). In base a questo risultato

possiamo affermare che Mantis è più robusto ai bit flip indotti nella memoria rispetto a

quelli indotti nel codice.

Figura 5.3: Grafico a torta che riporta i risultati degli esperimenti di iniezione in memoria

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

98

Per brevità nella tabella seguente riportiamo solo le locazioni ottenute dal tool, il numero

di esperimenti ad essi associati, le procedure ed i tipi di errore riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

1dde select 0 8 0 0

2e62 __vector_21 0 0 16 0

2e78 __vector_21 0 0 8 0

30a6 __vector_22 0 0 24 0

432e dispatcher 0 0 24 8

1cfa atmel_flash_init 0 0 0 8

4346 dispatcher 0 0 32 8

441a dispatcher 0 0 32 8

444e mos_thread_exit 0 0 8 0

477c mos_thread_new 0 0 0 8

4880 mos_thread_resume_noints 0 0 8 0

4f0e mos_mutex_unlock 0 8 0 0

5084 mos_sem_post_dispatch 0 0 8 0

563a __vector_12 0 0 0 8

571c __vector_12 0 0 8 40

5742 __vector_12 0 0 0 8

9d6 com_init 0 0 0 8

b14 com_swap_bufs 0 0 0 16

Dalla tabella si nota che si verificano solo 16 casi di errori di tipo Crash distribuiti

uniformemente in due studi di fault injection, analizziamo in maggior dettaglio quello

relativo alla locazione 4f0e. Riportiamo di seguito una porzione di codice della procedura

Tabella 5.3: Parametri utilizzati per la campagna di fault injection in memoria e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

99

mos_mutex_unlock che contiene al suo interno la locazione 4f0e:

4f04: cf 93 push r28

4f06: df 93 push r29 4f08: ec 01 movw r28, r24 4f0a: 00 91 f6 04 lds r16, 0x04F6 4f0e: 10 91 f7 04 lds r17, 0x04F7 4f12: 0e 94 4f 20 call 0x409e ; 0x409e <mos_disable_ints> 4f16: f8 2e mov r15, r24 4f18: 88 81 ld r24, Y

4f1a: 99 81 ldd r25, Y+1 ; 0x01

In questo caso il fault iniettato provoca la modifica di uno dei bit del registro r17 inoltre il

contenuto modificato del registro viene scritto nella locazione 0x04F7 (nella sezione di

Injection viene inserita l’istruzione sts 0x04F7, r17) . In questo caso l’errore di tipo Crash

può essere dovuto alla modifica della locazione 04F7 la quale probabilmente contiene al

suo interno una parte di un indirizzo (infatti a supporto della nostra tesi si nota, dalla

porzione di codice riportata, che nel registro r16 viene caricato il contenuto della locazione

precedente di indirizzo 0x04F6). L’errore di Crash si manifesta quando la procedura in

esame termina ossia quando viene restituito il controllo al chiamante attraverso

l’istruzione ret, molto probabilmente perché l’indirizzo di ritorno non è più corretto.

Un altro studio di fault injection interessante è quello relativo alla locazione 2e62 in

quanto sono rilevati solo errori latenti. Riportiamo di seguito una porzione di codice della

procedura __vector_21 che contiene la locazione 2e62:

2e5c: 39 2b or r19, r25

2e5e: 30 93 e1 02 sts 0x02E1, r19 2e62: 20 93 e0 02 sts 0x02E0, r18 2e66: 89 ed ldi r24, 0xD9 ; 217 2e68: 92 e0 ldi r25, 0x02 ; 2 2e6a: 0e 94 2d 28 call 0x505a; 0x505a <mos_ sem_post_dispatch> 2e6e: ff 91 pop r31 2e70: ef 91 pop r30 2e72: bf 91 pop r27

In questo caso l’iniezione effettuata modificando uno dei bit del registro r18 modifica

anche il contenuto della locazione di memoria di indirizzo 02E0. Tuttavia gli errori rilevati

sono tutti errori latenti in quanto nelle immediate vicinanze dell’istruzione target

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

100

(istruzione in cui è stato iniettato il fault) non viene utilizzato né il valore contenuto nella

locazione di memoria di indirizzo 02E0 e nemmeno il valore contenuto nel registro r18.

Nel grafico successivo si riportano le percentuali degli errori, di tipo Crash ed Hang, che si

sono verificati nel corso dei 304 esperimenti in funzione dei cicli di latenza riscontrati.

Dall’istogramma si nota l’assenza degli errori di tipo Hang e che tutti gli errori di tipo

Crash hanno una latenza che non supera i 100 cicli. In particolare in base alla tabella 5.3

notiamo che su 304 esperimenti di fault injection si sono verificati solamente 16 casi di

errori di tipo Crash distribuiti in modo uniforme su due locazioni (nella locazione 1dde si

sono verificati 8 errori di tipo Crash con latenza nulla mentre nella locazione 4f0e si sono

verificati 8 errori di tipo Crash con latenza pari a 100 cicli macchina).

Figura 5.4: Latenza relativa all’iniezione in memoria

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

101

5.1.3 PC Error Injection

Il grafico a torta sottostante mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel registro PC. Sono stati

realizzati 432 esperimenti di fault injection raccolti in 12 studi step-by-step. Dal grafico si

nota che la quasi totalità (il 94,5%) degli errori rilevati è rappresentata da errori di tipo

Crash.

E’ importante notare che in questa tipologia di iniezione sono completamente assenti

errori di tipo Hang; questo comportamento è dovuto all’iniezione effettuata infatti quando

viene modificato il contenuto del registro PC ci sono solamente due possibilità: l’indirizzo

ottenuto non è valido e viene quindi rilevato un Crash error oppure l’indirizzo ottenuto è

valido e si effettua il salto ad un’altra porzione di codice, tuttavia in quest’ultimo caso non

si generano loop in quanto non viene modificata la condizione di terminazione di un

eventuale ciclo.

Per brevità nella tabella seguente riportiamo solo le locazioni ottenute dal tool, il numero

di esperimenti ad essi associati, le procedure ed i tipi di errore riscontrati.

Figura 5.5: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel PC

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

102

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

12e0 hardware_id_init 0 16 0 0

1f0 start 0 8 0 0

2232 mica2_battery_init 0 8 0 0

236 mos_led_init 0 8 0 0

284 mos_led_off 0 8 0 0

3116 __vector_22 0 8 0 0

3a2 plat_init 0 8 0 0

47cc mos_thread_wakeup_noints 0 96 0 0

4be0 mos_thread_sleep 0 96 0 0

4d70 mos_mem_alloc 0 48 8 16

4de6 mos_mem_free 0 8 0 0

51a2 mos_tlist_ordadd 0 96 0 0

Nel grafico successivo si riportano le percentuali degli errori, di tipo Crash ed Hang, che si

sono verificati nel corso dei 432 esperimenti in funzione dei cicli di latenza riscontrati.

Tabella 5.4: Parametri utilizzati per la campagna di fault injection nel PC e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

103

Dall’istogramma si nota come non siano presenti errori di tipo Hang e come tutti gli errori

di tipo Crash abbiano una latenza che non supera i 60 cicli (in particolare il valore di

latenza riscontrato è nullo in quanto il microcontrollore si accorge subito che l’indirizzo

non è valido e blocca l’esecuzione dell’applicazione). Inoltre dalla tabella 5.4 si nota come

in tutti gli studi di fault injection sono stati rilevati errori di tipo Crash.

5.1.4 SP Error Injection

Il grafico a torta sottostante mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel registro SP. Sono stati

realizzati 280 esperimenti di fault injection raccolti in 20 studi step-by-step. Dal grafico si

nota come la percentuale maggiore di occorrenza sia quella degli errori di tipo Crash

(62,1%). Questo risultato deriva dalla struttura di Mantis, infatti quest’ultimo essendo un

sistema operativo multithread associa uno stack ad ogni thread e realizza meccanismi per

Figura 5.6: Latenza relativa all’iniezione nel registro PC

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

104

il controllo dei limiti di tale area, quindi quando in seguito all’iniezione del fault si

modifica il contenuto del registro SP si può tentare l’accesso ad un’area non consentita e

quindi viene bloccata l’esecuzione dell’applicazione.

Nella tabella seguente si riportano solo le locazioni ottenute dal tool, il numero di

esperimenti ad essi associati, le procedure e i tipi di errore riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

11fe read_byte 0 7 0 1

1246 hardware_id_init 2 5 1 0

2ee4 adc_read_channel16 0 4 1 3

30a8 __vector_22 0 8 0 0

4338 dispatcher 0 40 0 0

444a mos_thread_exit 0 0 8 0

Figura 5.7: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel registro SP

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

105

46e6 mos_thread_new 0 8 0 32

4786 mos_thread_new 0 16 0 0

4b90 check_sleep_time 2 6 0 0

4be8 mos_thread_sleep 1 4 0 43

4cba mos_mem_alloc 0 8 0 0

4f00 mos_mutex_unlock 0 8 0 0

4f4c mos_mutex_lock 0 7 0 1

4f9e mos_mutex_lock 0 8 0 0

502c mos_sem_post 5 3 0 0

505a mos_sem_post_dispatch 1 15 0 0

5642 __vector_12 0 8 0 0

5652 __vector_12 0 8 0 0

5732 __vector_12 0 8 0 0

9d8 com_init 5 3 0 0

Dalla tabella si nota, rispetto ai casi precedenti, una variabilità maggiore rispetto alla

variazione del bit-flip e del ciclo di iniezione. Visto che la maggior parte degli errori è di

tipo Crash (ed abbiamo già spiegato intuitivamente il perché) è interessante approfondire

uno studio in cui sono stati rilevati errori di altra natura, ad esempio quelli di tipo Hang.

Riportiamo di seguito una porzione di codice della procedura mos_sem_post che contiene

la locazione 502c:

502a: 0f 93 push r16

502c: 1f 93 push r17 502e: 8c 01 movw r16, r24 5030: 0e 94 4f 20 call 0x409e ; 0x409e <mos _disable_ints> 5034: f8 2e mov r15, r24 5036: f8 01 movw r30, r16

Lo studio di fault injection relativo alla locazione 502c rileva la presenza di 5 casi di errori

di tipo Hang, questo probabilmente è dovuto alla presenza dell’istruzione di call (chiamata

Tabella 5.5: Parametri utilizzati per la campagna di fault injection nel registro SP e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

106

a procedura) nelle vicinanze dell’istruzione target. Infatti in seguito all’iniezione del fault

viene modificato il contenuto dello SP e di conseguenza in seguito alla chiamata a

procedura l’indirizzo di ritorno (che è salvato nello stack) potrebbe essere salvato in

locazioni non libere sovrascrivendo valori esistenti. In questo caso si può innescare un

ciclo nel momento in cui la procedura in esame restituisce il controllo al chiamante, infatti

visto che sono state sovrascritte alcune locazioni dello stack l’indirizzo di ritorno potrebbe

non essere più quello corretto. Per sostenere questa tesi riportiamo di seguito una porzione

di codice relativa alla procedura dispatcher che contiene la locazione 4338:

4336: af 92 push r10

4338: 9f 92 push r9 433a: 8f 92 push r8 433c: 7f 92 push r7 433e: 6f 92 push r6 4340: 5f 92 push r5 4342: 4f 92 push r4 4344: 3f 92 push r3 4346: 2f 92 push r2 4348: 8d b7 in r24, 0x3d ; 61 434a: 9e b7 in r25, 0x3e ; 62 434c: e0 91 f6 04 lds r30, 0x04F6 4350: f0 91 f7 04 lds r31, 0x04F7 4354: 91 83 std Z+1, r25 ; 0x01 4356: 80 83 st Z, r24 4358: 84 85 ldd r24, Z+12 ; 0x0c 435a: 81 30 cpi r24, 0x01 ; 1

E’ importante notare come in questo caso non siano presenti istruzioni di call vicino

all’istruzione target. In particolare, lo studio di fault injection sulla locazione in esame

riporta tutti errori di tipo Crash in quanto in seguito alla modifica del registro SP, vengono

sovrascritte locazioni dello stack e quindi quando la procedura termina restituendo il

controllo al chiamante (attraverso l’esecuzione dell’istruzione ret) l’indirizzo di ritorno

non è valido e l’esecuzione dell’applicazione viene interrotta.

Nel grafico successivo si riportano le percentuali degli errori, di tipo Crash ed Hang, che si

sono verificati nel corso dei 280 esperimenti in funzione dei cicli di latenza riscontrati.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

107

Dall’istogramma si nota che per questa tipologia di iniezione la latenza ha una variabilità

maggiore. In particolare la maggior parte degli errori (il 55,2%) ha una latenza che non

supera i 120 cicli. Dalla tabella 5.5 si nota che su 280 esperimenti di fault injection si

sono verificati 16 casi di errori di tipo Hang (distribuiti su più locazioni e con valore di

latenza che varia da 100 cicli fino ad arrivare in un caso isolato anche a 1475058 cicli) e

ben 174 casi di errori di tipo Crash (distribuiti su quasi tutte le locazioni e con valore di

latenza che varia a partire da un valore nullo fino ad arrivare ad un valore di 7271 cicli

macchina).

5.1.5 SR Error Injection

Il grafico a torta sottostante mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel registro SR. Sono stati

Figura 5.8: Latenza relativa all’iniezione nel registro SP

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

108

totalizzati 304 esperimenti di fault injection raccolti in 14 studi step-by-step. Dal grafico si

nota che la percentuale di occorrenza maggiore (55,3%) è quella relativa agli errori latenti;

questo comportamento è strettamente legato al tipo di iniezione effettuata, infatti il fault

iniettato modifica uno dei bit del registro SR che con buona probabilità non è quello

utilizzato dall’istruzione target, inoltre dato che l’esecuzione di quasi tutte le istruzioni del

microcontrollore modifica lo stato del registro SR è possibile che già dopo poche

istruzioni (dal punto di iniezione) venga modificato il contenuto del registro SR evitando il

manifestarsi del fault.

Nella tabella seguente si riportano solo le locazioni ottenute dal tool, il numero di

esperimenti ad essi associati, le procedure e i tipi di errore riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

12e2 hardware_id_init 48 0 0 0

Figura 5.9: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel registro SR

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

109

3118 __vector_22 0 0 0 16

312a __vector_22 0 0 16 0

318c dev_ioctl_DEV_AVR_EEPROM 0 0 8 0

3272 dev_read_DEV_AVR_EEPROM 0 0 0 8

40a0 mos_disable_ints 0 0 0 8

4130 mos_thread_resume_noints_nodispatch 0 0 8 0

418a idle_mode 0 0 8 0

41d6 idle_loop 0 0 0 8

430a dispatcher 0 0 72 8

4488 mos_thread_exit 0 0 8 0

46a8 mos_thread_new 0 0 8 24

47d2 mos_thread_wakeup_noints 0 0 40 8

4cda mos_mem_alloc 0 8 0 0

Dalla tabella si nota che su 304 esperimenti di fault injection si sono verificati solo 8 casi

di errori di tipo Crash (nella locazione 4cda) e 48 casi di errori di tipo Hang (nella

locazione 12e2). Per una maggiore comprensione analizziamo in dettaglio i casi di errori

di tipo Hang; riportiamo di seguito una porzione di codice della procedura

hardware_id_init che contiene la locazione 12e2:

12de: 82 e0 ldi r24, 0x02 ; 2

12e0: c9 36 cpi r28, 0x69 ; 105 12e2: d8 07 cpc r29, r24 12e4: c9 f7 brne .-14 ; 0x12d8 <h ardware_id_init+0x96> 12e6: 0e 94 fe 08 call 0x11fc ; 0x11fc <read _byte> 12ea: d4 98 cbi 0x1a, 4 ; 26 12ec: dc 98 cbi 0x1b, 4 ; 27

E’ interessante notare che l’iniezione del fault modifica uno dei bit del registro SR e che

tale modifica fa in modo che la condizione del salto relativo sia sempre verificata. Quindi

trattandosi di un salto relativo con valore dello spiazzamento negativo si genera un loop.

Tabella 5.6: Parametri utilizzati per la campagna di fault injection nel registro SR e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

110

Nel grafico successivo si riportano le percentuali degli errori, di tipo Crash ed Hang, che si

sono verificati nel corso dei 304 esperimenti in funzione dei cicli di latenza riscontrati.

Dall’istogramma si nota che gli errori di tipo Crash hanno una latenza che non supera i 60

cicli (con il valore minimo riscontrato che è nullo) mentre quelli di tipo Hang hanno una

latenza superiore ai 160 cicli (il massimo valore di latenza riscontrato è di 22540 cicli

macchina).

5.1.6 Mantis Total Error Injection

Il grafico a torta sottostante raggruppa i risultati delle campagne di fault injection, ottenuti

attraverso l’utilizzo dell’AVR-INJECT Tool, effettuando le differenti tipologie di

iniezione. Sono stati realizzati un totale di 1752 esperimenti raccolti in 76 studi step-by-

step. Dal grafico si nota che la percentuale di occorrenza maggiore (anche se di poco con il

36,8%) è quella relativa agli errori di tipo Crash. E’ importante notare che è elevata anche

Figura 5.10: Latenza relativa all’iniezione nel registro SR

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

111

la percentuale di occorrenza degli errori da approfondire (31,1%) e quella degli errori

latenti (25,7%) mentre invece è bassa quella degli errori di tipo Hang (solamente il 6,4%).

Inoltre in base alle tabelle riportate nei paragrafi precedenti si ricava che su 1752

esperimenti di fault injection si sono manifestati solo 113 casi di errori di tipo Hang

concentrati in dieci locazioni differenti.

Le percentuali degli errori, di tipo Crash ed Hang, che si sono verificati nel corso dei 1752

esperimenti in funzione dei cicli di latenza riscontrati, sono mostrate nel grafico

sottostante.

Figura 5.11: Grafico a torta che riporta i risultati globali degli esperimenti di iniezione.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

112

Dall’istogramma si nota che la percentuale degli errori di tipo Crash è molto più grande di

quella degli errori di tipo Hang. Inoltre mentre per gli errori di tipo Hang la latenza varia

in un range abbastanza ampio (dal minimo valore di latenza riscontrato che è di 70 cicli

macchina al massimo valore che è di 1475058 cicli macchina riscontrato in un caso

isolato) , nel caso di errori di tipo Crash il 69% ha una latenza che non supera i 60 cicli

(con un valore minimo di latenza che è nullo mentre il valore massimo riscontrato è di

7271 cicli macchina). In particolare il fatto di avere una latenza elevata risulta essere un

problema in quanto un’eventuale detector non potrebbe intervenire tempestivamente; un

detector ideale interviene (ossia rileva l’errore) subito dopo l’iniezione del fault (latenza

nulla).

Figura 5.12: Latenza totale in Mantis OS

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

113

5.2 Fault injection in TinyOS

Per analizzare in modo più dettagliato i risultati ottenuti in TinyOS, li presentiamo prima

suddivisi per tipologia di iniezione e poi successivamente in una visione di insieme.

5.2.1 Code Error Injection

Il grafico a torta sottostante mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel codice

dell’applicazione blink. Sono stati realizzati 312 esperimenti raccolti in 13 studi step-by-

step.

Su 312 esperimenti di fault injection effettuati nel codice dell’applicazione:

• il 25,6% degli esperimenti ha provato la robustezza dell’applicazione blink.

L’iniezione del guasto non ha influenzato il suo normale funzionamento.

• il 31,1% degli esperimenti ha riportato un caso di Hang Error .

• il 24,7% degli esperimenti ha riportato un caso di Crash Error.

Figura 5.13: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel codice

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

114

• il 18,6% degli esperimenti ha riportato un caso di errore che merita ulteriori

approfondimenti.

E’ importante notare che rispetto al grafico di figura 5.1 (iniezione nel codice di Mantis),

sono aumentate le percentuali di occorrenza degli errori di tipo Crash ed Hang mentre è

sensibilmente diminuita la percentuale degli errori da approfondire. L’aumento della

percentuale di occorrenza degli errori di tipo Crash può essere considerato in modo

positivo, in quanto, relativamente all’iniezione nel codice, possiamo dire che in un certo

senso TinyOS è più “safe” (negli errori di tipo Crash viene interrotta l’esecuzione

dell’applicazione evitando con maggiore probabilità il verificarsi di danni gravi). Invece

rispetto all’aumento della percentuale di occorrenza degli errori di tipo Hang e alla

diminuzione di quella degli errori da approfondire non possiamo effettuare osservazioni

interessanti in quanto entrambe le tipologie presentano soltanto aspetti negativi.

Nella tabella seguente si riportano le locazioni generate dal tool con le relative procedure,

il numero di esperimenti di fault injection eseguiti per ogni locazione ed i tipi di errore

riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

1006 HplCC1000P$HplCC1000$write 4 2 0 2

12e __nesc_atomic_end 0 0 0 8

143a VirtualizeTimerC$0$TimerFrom$startOneShotAt 0 0 0 32

14e6 AlarmToTimerC$0$start 0 0 32 0

1536 AlarmToTimerC$0$start 5 2 0 1

16a6 Atm128AlarmAsyncP$0$TimerCtrl$getInterruptFlag 48 0 0 0

1834 VirtualizeTimerC$0$fireTimers 0 32 0 0

1876 VirtualizeTimerC$0$Timer$fired 0 24 0 0

1ad2 SchedulerBasicP$TaskBasic$postTask 0 16 0 0

1b0c SchedulerBasicP$pushTask 40 0 0 0

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

115

21c8 HplAtm128Timer0AsyncP$stabiliseTimer0 0 0 48 0

72a HplAtm128GeneralIOPinP$6$IO$makeInput 0 0 0 8

fe __nesc_atomic_start 0 1 0 7

Analizziamo di seguito due casi notevoli scelti dalla tabella che ci permettono di

comprendere meglio come è stato possibile, in seguito all’iniezione effettuata, ottenere le

particolari tipologie di errori. Come casi notevoli abbiamo scelto la locazione 1b0c in cui

sono rilevati 40 errori di tipo Hang e la locazione 21c8 in cui sono rilevati 48 errori

latenti. Riportiamo di seguito una porzione di codice della procedura

SchedulerBasicP$pushTask che contenga al suo interno la locazione 1b0c:

1b08: 0f b6 in r0, 0x3f ; 63

1b0a: f8 94 cli 1b0c: de bf out 0x3e, r29 ; 62 1b0e: 0f be out 0x3f, r0 ; 63 1b10: cd bf out 0x3d, r28 ; 61 1b12: 89 83 std Y+1, r24 ; 0x01 1b14: 89 81 ldd r24, Y+1 ; 0x01 1b16: 0e 94 b7 0d call 0x1b6e 1b1a: 88 23 and r24, r24

In questo caso l’iniezione del fault provoca la modifica di uno dei bit del registro r29,

tuttavia visto che il valore contenuto nel registro r29 viene utilizzato per modificare la

parte alta del registro SP (SPH) di conseguenza in seguito all’iniezione viene modificato

anche lo stack pointer. Questa modifica comporta la sovrascrittura di alcune locazioni

dello stack con relativa perdita di valori, in questo modo il loop può essere innescato nel

momento in cui la procedura in esame restituisce il controllo al chiamante in quanto

l’indirizzo di ritorno non coincide con quello salvato in precedenza nello stack.

Riportiamo di seguito il codice della procedura HplAtm128Timer0AsyncP$stabiliseTimer0

che contiene al suo interno la locazione 21c8:

21c2: cf 93 push r28

21c4: df 93 push r29 21c6: cd b7 in r28, 0x3d ; 61 21c8: de b7 in r29, 0x3e ; 62 21ca: e3 e5 ldi r30, 0x53 ; 83 21cc: f0 e0 ldi r31, 0x00 ; 0

Tabella 5.7: Parametri utilizzati per la campagna di fault injection nel codice e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

116

21ce: a3 e5 ldi r26, 0x53 ; 83 21d0: b0 e0 ldi r27, 0x00 ; 0 21d2: 8c 91 ld r24, X 21d4: 80 83 st Z, r24 21d6: e0 e5 ldi r30, 0x50 ; 80 21d8: f0 e0 ldi r31, 0x00 ; 0 21da: 80 81 ld r24, Z 21dc: 99 27 eor r25, r25 21de: 81 70 andi r24, 0x01 ; 1 21e0: 90 70 andi r25, 0x00 ; 0 21e2: 88 23 and r24, r24 21e4: c1 f7 brne .-16 ; 0x21d6 21e6: df 91 pop r29 21e8: cf 91 pop r28 21ea: 08 95 ret

L’istruzione target carica nel registro r29 il contenuto della parte alta del registro SP,

l’iniezione del fault comporta la modifica di uno dei bit del registro r29. In questo caso

abbiamo riportato l’intera procedura per far notare come in seguito all’iniezione del fault il

valore contenuto dal registro r29 non sia più utilizzato ed è per questo che sono stati

rilevati tutti errori latenti.

Nel grafico successivo sono riportate le percentuali degli errori di Crash ed Hang che si

sono verificati nel corso dei 312 esperimenti in funzione dei cicli di latenza riscontrati.

Figura 5.14: Latenza relativa all’iniezione nel codice

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

117

Dall’istogramma si nota come l’89% degli errori abbiano una latenza che non supera gli

80 cicli. Inoltre dalla tabella 5.7 si nota che su 312 esperimenti di fault injection si sono

verificati 97 casi di errori di tipo Hang (distribuiti in quattro locazioni differenti con

latenza che varia da 70 a 645 cicli macchina ) e 77 casi di errori di tipo Crash (distribuiti in

sei locazioni differenti con valori di latenza che vanno da 0 e non superano i 60 cicli

macchina). Infine possiamo notare che rispetto all’istogramma di figura 5.2 (latenza nel

codice di Mantis OS), i cicli di latenza si sono ridotti sia per gli errori di tipo Crash

(passando da 70 a 60 cicli macchina) sia per quelli di tipo Hang (per la maggior parte di

essi la latenza è passata da un valore superiore a 160 ad un valore che non supera i 70 cicli

macchina). Questo comportamento è preferibile in quanto permetterebbe ad un eventuale

detector di intervenire più tempestivamente.

5.2.2 Memory Error Injection

Nel grafico seguente sono riportati i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti in memoria. In particolare,

sono stati realizzati 328 esperimenti di fault injection raccolti in 14 studi step-by-step.

Dal grafico si nota che la percentuale di occorrenza maggiore è quella relativa agli errori

latenti con il 44,2%. Rispetto ai risultati ottenuti in Mantis OS per questa tipologia di

iniezione (basta osservare il grafico a torta dei risultati di figura 5.3) notiamo la presenza

degli errori di tipo Hang e la diminuzione delle percentuali di occorrenza di quelli latenti e

da approfondire. Questo ci permette di affermare che, relativamente all’iniezione dei fault

in memoria, Mantis OS è più robusto rispetto a TinyOS.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

118

Di seguito riportiamo una tabella che contiene le locazioni generate (in modo casuale) dal

tool con le relative procedure, il numero di esperimenti di fault injection effettuati con la

relativa classificazione degli errori.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

131c VirtualizeTimerC$0$TimerFrom$getNow 8 0 0 0

13e8 Atm128AlarmAsyncP$0$Alarm$stop 0 0 0 32

140e VirtualizeTimerC$0$TimerFrom$startOneShotAt 32 0 0 0

14c4 AlarmToTimerC$0$Timer$startOneShotAt 0 0 8 0

18b4 VirtualizeTimerC$0$Timer$fired 13 15 0 4

1942 BlinkC$Timer1$fired 3 5 0 0

1cee Atm128AlarmAsyncP$0$setInterrupt 0 0 8 24

1f40 AlarmToTimerC$0$fired$runTask 8 0 0 0

Figura 5.15: Grafico a torta che riporta i risultati degli esperimenti di iniezione in memoria

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

119

20b2 VirtualizeTimerC$0$Timer$startPeriodic 0 0 8 0

2178 __vector_15 0 0 48 0

219c __vector_15 8 0 0 0

21ec HplAtm128Timer0AsyncP$Compare$fired 0 0 48 0

2248 Atm128AlarmAsyncP$0$Compare$fired 0 0 25 23

81c HplAtm128GeneralIOPinP$31$IO$set 0 0 0 8

Analizziamo in maggior dettaglio lo studio di fault injection relativo alla locazione 140e in

cui sono rilevati tutti errori di tipo Hang. Quindi riportiamo una porzione di codice della

procedura VirtualizeTimerC$0$TimerFrom$startOneShotAt che contiene la locazione

140e di interesse:

1408: 0f 93 push r16

140a: 1f 93 push r17 140c: cf 93 push r28 140e: df 93 push r29 1410: cd b7 in r28, 0x3d ; 61 1412: de b7 in r29, 0x3e ; 62 1414: 28 97 sbiw r28, 0x08 ; 8 1416: 0f b6 in r0, 0x3f ; 63 1418: f8 94 cli 141a: de bf out 0x3e, r29 ; 62 141c: 0f be out 0x3f, r0 ; 63 141e: cd bf out 0x3d, r28 ; 61 1420: 69 83 std Y+1, r22 ; 0x01 1422: 7a 83 std Y+2, r23 ; 0x02 1424: 8b 83 std Y+3, r24 ; 0x03

In questo caso l’iniezione del fault modifica uno dei bit del registro r29 prima che il suo

contenuto venga salvato nello stack. Questo salvataggio viene effettuato per non

modificare il valore originario contenuto nel registro in quanto all’interno della procedura

viene utilizzato il registro r29 modificandone il valore. Inoltre il fault con molta

probabilità sarà attivato nel momento in cui verrà ripristinato nel registro r29 il valore

salvato nello stack. Si verificano degli errori di tipo Hang in quanto è possibile che il

valore del registro r29 all’interno della procedura chiamante sia utilizzato per il calcolo di

Tabella 5.8: Parametri utilizzati per la campagna di fault injection in memoria e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

120

una condizione di terminazione di un ciclo. A rafforzare la nostra ipotesi c’è anche il

valore di latenza riscontrato che è di 1724 cicli macchina.

Di seguito approfondiamo lo studio di fault injection relativo alla locazione 21ec

riportando il codice della procedura HplAtm128Timer0AsyncP$Compare$fired:

21ec: cf 93 push r28

21ee: df 93 push r29 21f0: cd b7 in r28, 0x3d ; 61 21f2: de b7 in r29, 0x3e ; 62 21f4: 0e 94 ff 10 call 0x21fe 21f8: df 91 pop r29 21fa: cf 91 pop r28 21fc: 08 95 ret

In questo caso l’iniezione del fault modifica un bit del registro r28 prima che il suo

contenuto venga salvato all’interno dello stack. In base agli esperimenti di fault injection

eseguiti sono stati rilevati tutti errori latenti in quanto con molta probabilità la procedura

chiamante modifica il registro r28 senza utilizzare il valore contenuto.

Nel grafico successivo riportiamo le percentuali degli errori di Crash ed Hang che si sono

verificati nel corso dei 328 esperimenti in funzione dei cicli di latenza riscontrati.

Figura 5.16: Latenza relativa all’iniezione in memoria

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

121

Dall’istogramma si nota che il 64% degli errori (tipo Crash ed Hang) ha una latenza che

supera i 160 cicli macchina. In particolare per gli errori di tipo Hang il valore massimo di

latenza riscontrato è di 1724 cicli macchina mentre per quelli di tipo Crash è di 614 cicli

macchina (per questo tipo di errori la latenza minima è nulla). Inoltre se confrontiamo

questo istogramma con quello di figura 5.4 (istogramma della latenza degli errori in

memoria di Mantis OS), notiamo la presenza degli errori di tipo Hang e l’aumento della

latenza per gli errori di tipo Crash.

5.2.3 PC Error Injection

Il grafico a torta sottostante riporta i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel registro PC. In

particolare sono stati realizzati 280 esperimenti raccolti in 13 studi step-by-step. E’

interessante notare che per questa tipologia di iniezione gli errori rilevati sono tutti di tipo

Crash.

Figura 5.17: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel registro PC

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

122

Questo risultato, come già spiegato nel paragrafo relativo all’iniezione nel codice di

Mantis OS, non ci meraviglia in quanto è dovuto alla particolare iniezione effettuata.

Infatti quando viene modificato il contenuto del registro PC ci sono solamente due

possibilità: o l’indirizzo ottenuto non è valido e viene quindi rilevato un Crash error

oppure l’indirizzo ottenuto è valido e si effettua il salto ad un’altra porzione di codice. Nel

nostro caso, in tutti gli esperimenti di fault injection effettuati è stato ottenuto un indirizzo

non valido e quindi il microcontrollore ha bloccato l’esecuzione dell’applicazione.

Confrontando questo grafico con quello in figura 5.5 (grafico a torta dei risultati degli

esperimenti di iniezione nel registro PC in Mantis OS), notiamo l’assenza degli errori

latenti e di quelli da approfondire, questo come già spiegato è da attribuire agli indirizzi

non validi ottenuti in seguito all’iniezione del fault.

Nella tabella seguente riportiamo le locazioni generate in modo casuale dal tool con le

relative procedure, il numero di esperimenti di fault injection eseguiti per ognuna di esse e

i tipi di errori rilevati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

1006 HplCC1000P$HplCC1000$write 0 8 0 0

12e __nesc_atomic_end 0 8 0 0

143a VirtualizeTimerC$0$TimerFrom$startOneShotAt 0 32 0 0

14e6 AlarmToTimerC$0$start 0 32 0 0

1536 AlarmToTimerC$0$start 0 8 0 0

16a6 Atm128AlarmAsyncP$0$TimerCtrl$getInterruptFlag 0 16 0 0

1834 VirtualizeTimerC$0$fireTimers 0 32 0 0

1876 VirtualizeTimerC$0$Timer$fired 0 24 0 0

1ad2 SchedulerBasicP$TaskBasic$postTask 0 16 0 0

1b0c SchedulerBasicP$pushTask 0 40 0 0

21c8 HplAtm128Timer0AsyncP$stabiliseTimer0 0 48 0 0

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

123

72a HplAtm128GeneralIOPinP$6$IO$makeInput 0 8 0 0

fe __nesc_atomic_start 0 8 0 0

Di seguito riportiamo il grafico con le percentuali di occorrenza degli errori di Crash ed

Hang che si sono verificati nel corso dei 280 esperimenti di fault injection in funzione dei

cicli di latenza riscontrati.

Dall’istogramma si nota che tutti gli errori hanno una latenza che non supera i 60 cicli (in

particolare il valore di latenza riscontrato è nullo). In questo caso confrontando

l’istogramma con quello di figura 5.6 (relativo alla latenza degli esperimenti di fault

injection nel registro PC in Mantis OS) notiamo che sono perfettamente identici.

5.2.4 SP Error Injection

Il grafico di figura 5.19 mostra i risultati della campagna di fault injection ottenuti,

attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel registro SR. In

Tabella 5.9: Parametri utilizzati per la campagna di fault injection nel registro PC e outcome

Figura 5.18: Latenza relativa all’iniezione nel registro PC

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

124

particolare sono stati realizzati 296 esperimenti raccolti in 30 studi step-by-step. Dal

grafico si nota come la percentuale di occorrenza maggiore è quella relativa agli errori di

tipo Hang con il 57,3%.

Confrontando questo grafico con quello in figura 5.7 (grafico a torta dei risultati degli

esperimenti di iniezione nel registro SP in MantisOS), notiamo che la percentuale degli

errori da approfondire è notevolmente diminuita mentre quella degli errori di tipo Hang è

aumentata di molto. Questa osservazioni non ci permette particolari spunti di riflessione in

quanto entrambe le tipologie di errore presentano soltanto aspetti negativi. Tuttavia

sempre dal confronto possiamo notare che la percentuale di occorrenza degli errori di tipo

Crash è diminuita molto (passando dal 62,1% di Mantis al 39,0% di TinyOS) e che sono

proprio assenti gli errori latenti. L’assenza degli errori latenti ci permette di dire che,

relativamente all’iniezione dei fault nel registro SP, Mantis OS in un certo senso è più

robusto di TinyOS (infatti non è possibile escludere che gli errori latenti possono essere

Figura 5.19: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel registro SP

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

125

attivati successivamente). Invece la diminuzione della percentuale di occorrenza per gli

errori di tipo Crash ci porta ad affermare che, relativamente all’iniezione dei fault nel

registro SP, Mantis OS è in un certo senso più “safe” di TinyOS.

Riportiamo di seguito una tabella contenente le locazioni generate dal tool con le rispettive

procedure, il numero di esperimenti di fault injection realizzati per ognuna di esse e gli

errori riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

117a SchedulerBasicP$Scheduler$runNextTask 6 2 0 0

12e2 VirtualizeTimerC$0$TimerFrom$getNow 5 3 0 0

1336 AlarmToTimerC$0$Timer$getNow 5 2 0 1

140 __nesc_atomic_end 6 2 0 0

1468 AlarmToTimerC$0$Timer$startOneShotAt 5 3 0 0

15bc Atm128AlarmAsyncP$0$Counter$get 6 2 0 0

16ac Atm128AlarmAsyncP$0$TimerCtrl$getInterruptFlag 7 1 0 0

16b4 HplAtm128Timer0AsyncP$TimerCtrl$getInterruptFlag 4 4 0 0

16c8 Atm128AlarmAsyncP$0$Compare$get 4 4 0 0

1706 HplAtm128Timer0AsyncP$Compare$get 5 3 0 0

170e Atm128AlarmAsyncP$0$Timer$get 4 4 0 0

1852 VirtualizeTimerC$0$Timer$fired 3 5 0 0

20b2 VirtualizeTimerC$0$Timer$startPeriodic 4 3 0 1

219c __vector_15 5 3 0 0

21aa __vector_15 3 5 0 0

21bc __vector_15 3 5 0 0

21c4 HplAtm128Timer0AsyncP$stabiliseTimer0 3 5 0 0

248 RealMainP$Scheduler$init 5 2 0 1

4cc LedsP$Init$init 4 3 0 1

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

126

7da HplAtm128GeneralIOPinP$28$IO$set 5 3 0 0

808 HplAtm128GeneralIOPinP$31$IO$set 5 3 0 0

8b0 HplAtm128GeneralIOPinP$15$IO$makeInput 5 2 0 1

8f6 HplAtm128GeneralIOPinP$11$IO$makeInput 4 3 0 1

940 ecombine 16 15 0 1

98a PlatformP$power_init 4 3 0 1

9c8 RealMainP$SoftwareInit$init 6 1 0 1

b1e HplAtm128Timer0AsyncP$Compare$start 3 3 0 2

d2 __nesc_atomic_start 25 15 0 0

fc6 SchedulerBasicP$TaskBasic$runTask 4 4 0 0

b72 __nesc_enable_interrupt 5 3 0 0

Dalla tabella si nota che la variabilità degli errori rispetto alla variazione del bit-flip e del

ciclo di iniezione è maggiore rispetto agli altri casi. Analizziamo di seguito un caso

notevole in cui c’è variabilità rispetto al bit-flip. Riportiamo di seguito una porzione di

codice relativa alla procedura SchedulerBasicP$TaskBasic$runTask che contenga la

locazione fc6:

fbc: 0f b6 in r0, 0x3f ; 63

fbe: f8 94 cli fc0: de bf out 0x3e, r29 ; 62 fc2: 0f be out 0x3f, r0 ; 63 fc4: cd bf out 0x3d, r28 ; 61 fc6: df 91 pop r29 fc8: cf 91 pop r28 fca: 08 95 ret

In questo tipo di iniezione viene modificato un bit del registro SP, questo comporta che le

successive istruzioni che utilizzano lo stack possono o sovrascrivere delle locazioni già

utilizzate oppure prelevare dallo stack valori sbagliati. Un errore di tipo Crash si verifica

nel momento in cui la procedura in esame restituisce il controllo al chiamante e l’indirizzo

di ritorno prelevato dallo stack non è un indirizzo valido. Invece un errore di tipo Hang si

Tabella 5.10: Parametri utilizzati per la campagna di fault injection nel registro SP e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

127

può verificare quando la procedura in esame restituisce il controllo al chiamante e

l’indirizzo di ritorno prelevato dallo stack anche se valido non è quello corretto.

Si riporta di seguito il grafico con le percentuali di occorrenza degli errori di Crash ed

Hang in funzione dei cicli di latenza riscontrati.

Dall’istogramma si nota che la maggioranza degli errori (circa l’80%) ha una latenza che

non supera i 100 cicli macchina. Inoltre rispetto all’istogramma in figura 5.8 (relativo alla

latenza negli esperimenti in MantisOS nel registro SP) notiamo la diminuzione della

latenza per gli errori di tipo Hang (infatti in questo caso più del 40% di essi ha una latenza

che non supera i 100 cicli macchina). In particolare per quanto riguarda gli errori di tipo

Hang il valore massimo di latenza riscontrato è di 6076 cicli macchina mentre per quelli di

tipo Crash il valore massimo di latenza riscontrato è di 180000 cicli macchina (di tratta

tuttavia di un caso isolato infatti se si esclude questo valore la latenza più alta riscontrata è

di 391 cicli macchina).

Figura 5.20: Latenza relativa all’iniezione nel registro SP

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

128

5.2.5 SR Error Injection

Riportiamo di seguito il grafico a torta che mostra i risultati della campagna di fault

injection ottenuti, attraverso l’utilizzo dell’AVR-INJECT Tool, iniettando guasti nel

registro SR. In particolare sono stati realizzati 304 esperimenti di fault injection raccolti in

14 studi step-by-step. Dal grafico si nota che gli errori rilevati sono quasi tutti errori latenti

(92,1%), questo risultato è strettamente legato al tipo di iniezione effettuata. Infatti nel

caso specifico il fault iniettato modifica uno dei bit del registro SR che con molta

probabilità non è quello utilizzato dall’istruzione target (istruzione in cui si inietta il fault),

inoltre dato che l’esecuzione di quasi tutte le istruzioni del microcontrollore modifica uno

o più bit del registro SR è possibile che già dopo poche istruzioni venga annullato l’effetto

del fault.

Confrontando questo grafico con quello in figura 5.9 (grafico a torta dei risultati degli

esperimenti di iniezione nel registro SR in Mantis OS), notiamo che la percentuale di

occorrenza degli errori da approfondire è notevolmente diminuita mentre quella degli

errori di tipo Hang è diventata completamente nulla. Inoltre un aspetto molto importante è

Figura 5.21: Grafico a torta che riporta i risultati degli esperimenti di iniezione nel registro SR

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

129

il considerevole aumento degli errori latenti (si passa dal 55,3% di Mantis al 92,1% di

TinyOS) questo ci porta ad affermare che, relativamente all’iniezione nel registro SP,

TinyOS è in qualche modo più robusto di Mantis OS.

Nella tabella seguente sono riportate le locazioni generate dal tool con le relative

procedure, il numero di esperimenti di fault injection eseguiti per ognuna di esse e i tipi di

errori riscontrati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

1000 HplCC1000P$HplCC1000$write 0 0 16 0

1450 VirtualizeTimerC$0$TimerFrom$startOneShotAt 0 0 32 0

1784 VirtualizeTimerC$0$fireTimers 0 0 8 0

1996 HplAtm128GeneralIOPinP$IO$toggle 0 0 8 0

1bce Atm128AlarmAsyncP$0$Alarm$startAt 0 0 32 0

1cda Atm128AlarmAsyncP$0$setInterrupt 0 0 8 0

1da2 Atm128AlarmAsyncP$0$setInterrupt 0 0 48 0

1e2c Atm128AlarmAsyncP$0$setOcr0 0 8 0 0

1e68 Atm128AlarmAsyncP$0$TimerAsync$compareBusy 0 0 32 0

20a6 VirtualizeTimerC$0$Timer$startPeriodic 0 0 24 0

20f2 VirtualizeTimerC$0$startTimer 0 0 24 0

2232 Atm128AlarmAsyncP$0$Compare$fired 0 0 48 0

ec2 mcombine 0 0 0 8

f26 SchedulerBasicP$popTask 0 0 0 8

E’ interessante analizzare lo studio in cui sono stati rilevati errori di tipo Crash. Quindi di

seguito riportiamo una porzione di codice della procedura

Atm128AlarmAsyncP$0$setOcr0 che contiene al suo interno la locazione 1e2c:

Tabella 5.11: Parametri utilizzati per la campagna di fault injection nel registro SR e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

130

1e22: b0 91 26 01 lds r27, 0x0126

1e26: 28 17 cp r18, r24 1e28: 39 07 cpc r19, r25 1e2a: 4a 07 cpc r20, r26 1e2c: 5b 07 cpc r21, r27 1e2e: 50 f4 brcc .+20 ; 0x1e44 1e30: 80 91 23 01 lds r24, 0x0123 1e34: 90 91 24 01 lds r25, 0x0124

In questo caso l’errore di tipo Crash è conseguenza di un valore di indirizzo non valido.

Infatti l’istruzione successiva a quella target (cpc r21,r27 ) è un’istruzione di salto relativo

condizionato che invece di essere eseguita all’interno della procedura viene eseguita nel

blocco di InstructionTarget e questo provoca la generazione di un indirizzo non valido. Di

seguito analizziamo in dettaglio lo studio di fault injection relativo alla locazione 20f2

riportando una porzione di codice della procedura VirtualizeTimerC$0$startTimer :

20ec: 33 27 eor r19, r19

20ee: c9 01 movw r24, r18 20f0: 88 0f add r24, r24 20f2: 99 1f adc r25, r25 20f4: 88 0f add r24, r24 20f6: 99 1f adc r25, r25 20f8: 88 0f add r24, r24 20fa: 99 1f adc r25, r25 20fc: 82 0f add r24, r18 20fe: 93 1f adc r25, r19 2100: 80 50 subi r24, 0x00 ; 0 2102: 9f 4f sbci r25, 0xFF ; 255 2104: 9a 83 std Y+2, r25 ; 0x02 2106: 89 83 std Y+1, r24 ; 0x01 2108: e9 81 ldd r30, Y+1 ; 0x01

In questo caso anche se il contenuto del registro r25 può subire delle modifiche in seguito

all’iniezione effettuata (qualora in seguito all’iniezione viene modificato proprio il bit C

del registro SR) non sono presenti all’interno della procedura in esame istruzioni di salto

condizionato che diversificano il flusso di esecuzione. Quindi è per questo motivo che tutti

gli errori rilevati, in riferimento alla locazione 20f2, sono errori latenti.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

131

Nel grafico successivo riportiamo le percentuali degli errori di Crash ed Hang che si sono

verificati durante i 304 esperimenti di fault injection in base ai cicli di latenza riscontrati.

Dalla tabella 5.11 notiamo che su 304 esperimenti di fault injection si sono verificati

soltanto 8 casi di errori latenti (tutti nella locazione 1e2c e con latenza nulla). Inoltre

rispetto all’istogramma di figura 5.10 (relativo alla latenza negli esperimenti di fault

injection in MantisOS nel registro SR) notiamo l’assenza di errori di tipo Hang.

5.2.6 TinyOS Total Error Injection

Di seguito riportiamo il grafico a torta che raggruppa i risultati delle campagne di fault

injection, ottenuti attraverso l’utilizzo dell’AVR-INJECT Tool, effettuando le differenti

tipologie di iniezione. In particolare sono stati realizzati un totale di 1520 esperimenti

raccolti in 84 studi step-by-step. Dal grafico si nota che le percentuali di occorrenza

Figura 5.22: Latenza relativa all’iniezione nel registro SR

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

132

maggiori sono relative agli errori di tipo Crash con il 34,5% e a quelli latenti con il 32,2%.

Seguono gli errori di tipo Hang con il 22,2% ed infine quelli da approfondire con solo

l’11,1% .

Rispetto al grafico di figura 5.11 (che riporta i risultati totali in Mantis OS) non possiamo

fare grandi considerazioni in quanto mentre diminuisce la percentuale di occorrenza degli

errori da approfondire allo stesso tempo aumenta quella degli errori di tipo Hang, infatti

queste due categorie di errori presentano soltanto aspetti negativi. Invece le percentuali di

occorrenza delle altre due categorie di errori restano pressoché invariate.

Nel grafico successivo riportiamo le percentuali degli errori, di tipo Crash ed Hang, che si

sono verificati nel corso dei 1520 esperimenti in funzione dei cicli di latenza riscontrati.

Figura 5.23: Grafico a torta che riporta i risultati globali degli esperimenti di iniezione.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

133

Dall’istogramma si nota che la percentuale degli errori di tipo Crash è più grande di quella

degli errori di tipo Hang. Inoltre mentre per gli errori di tipo Hang la latenza varia in un

range abbastanza ampio (da un valore minimo di 70 cicli ad un valore massimo di 6076

cicli macchina), nel caso di errori di tipo Crash il 52% ha una latenza che non supera i 60

cicli macchina (il valore minimo riscontrato è nullo mentre quello massimo escludendo il

caso isolato è di 614 cicli).

5.3 Risultati ottenuti con l’applicazione surge

Per dimostrare la generalità dell’AVR-INJECT Tool abbiamo deciso di effettuare alcuni

esperimenti di fault injection in una differente applicazione; è stata scelta l’applicazione

surge in quanto è un’applicazione tipica per le reti di sensore senza filo. In pratica questa

applicazione effettua delle misurazioni ed invia dei messaggi contenenti i valori ricavati.

Figura 5.24: Latenza totale

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

134

Visto che la campagna di fault injection da realizzare serve solo per dimostrare la

generalità del tool verranno effettuati soltanto 16 esperimenti (distribuiti uniformemente in

due studi) per ogni tipologia di iniezione. Quindi presentiamo direttamente i risultati totali

ottenuti sia per Mantis OS che per TinyOS.

5.3.1 Risultati totali in Mantis OS

Di seguito riportiamo il grafico a torta che riporta le percentuali di occorrenza delle

quattro tipologie di errori. In particolare sono stati realizzati 80 esperimenti di fault

injection raccolti in 10 studi step-by-step. Dal grafico si nota che la percentuale di

occorrenza maggiore è quella relativa agli errori da approfondire con il 55%.

Confrontando questo grafico con quello di figura 5.11 (che riporta i risultati totali ottenuti

in seguito agli esperimenti di fault injection effettuati sull’applicazione blink_led di

Mantis OS) notiamo l’assenza degli errori latenti. Tuttavia questo risultato dipende dal

Figura 5.25: Grafico a torta che riporta i risultati globali dell’iniezione

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

135

ridotto numero di esperimenti eseguiti (infatti sono stati realizzati soltanto 80 esperimenti

di fault injection rispetto ai 1752 eseguiti sull’applicazione blink_led). Invece restano

pressoché invariate le percentuali di occorrenza degli errori di tipo Crash ed Hang.

Per completezza di seguito riportiamo in forma tabellare le locazioni generate dal tool con

le rispettive procedure, il numero di esperimenti di fault injection eseguiti per ognuna di

esse con i tipi di errori rilevati.

Locazione Procedura Hang

Error

Crash

Error

Errori

latenti

Errori da

approfondire

1c8e com_send_IFACE_RADIO 0 0 0 8

517e dispatcher 0 0 0 8

55f8 mos_thread_wakeup_noints 0 8 0 0

612a set_alarm_timer 0 0 0 8

2cba mica2_sounder_init 0 8 0 0

64a0 __vector_12 0 8 0 0

5dce mos_sem_post 5 3 0 0

6f2c __prologue_saves 0 4 0 4

59a4 mos_sched_start 0 0 0 8

6e42 __udivmodsi4_ep 0 0 0 8

Nella tabella sono riportate le locazioni utilizzate in tutte le diverse tipologie di iniezione,

in particolare le prime due locazione sono relative all’iniezione nel codice, la terza e la

quarta locazione sono relative all’iniezione in memoria, la quinta e la sesta locazione sono

relative all’iniezione nel registro PC, la settima e l’ottava locazione sono relative

all’iniezione nel registro SP ed infine le ultime due locazioni sono relative all’iniezione nel

registro SR.

Tabella 5.12: Parametri globali utilizzati per la campagna di fault injection e outcome

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

136

Mostriamo di seguito le percentuali di occorrenza per gli errori di tipo Crash ed Hang al

variare dei cicli di latenza riscontrati.

Se confrontiamo questo grafico con quello di figura 5.12 (grafico della latenza totale in

Mantis riferito all’applicazione blink_led) notiamo una minore variabilità del valore di

latenza, tuttavia anche questo comportamento è da attribuirsi al ridotto numero di

esperimenti di fault injection eseguiti.

5.3.2 Risultati totali in TinyOS

Il seguente grafico a torta riporta le percentuali di occorrenza delle quattro tipologie di

errori. In particolare sono stati realizzati 80 esperimenti di fault injection raccolti in 10

studi step-by-step. Dal grafico si nota che gli errori di tipo Crash hanno la percentuale di

occorrenza maggiore con il 35% seguiti da quelli latenti con il 28,8%.

Figura 5.26: Latenza globale

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

137

Se confrontiamo questo grafico con quello di figura 5.23 (grafico che riporta i risultati

globali dell’iniezione nell’applicazione Blink di TinyOS ) notiamo che le percentuali di

occorrenza delle quattro tipologie di errori differiscono di poco, questo significa che il

ridotto numero di esperimenti eseguiti ha influito meno rispetto al caso precedente.

Per completezza di seguito mostriamo una tabella che riporta le locazioni generate dal tool

con le relative procedure, il numero di esperimenti eseguiti per ognuna di esse e i tipi di

errori riscontrati.

Locazione Procedura Hang Error Crash

Error

Errori

latenti

Errori da

approfondire

225c memset 0 8 0 0

558 main 1 0 0 7

1ba2 main 0 0 0 8

1e0e main 0 0 7 1

1b96 main 0 8 0 0

Figura 5.27: Grafico a torta che riporta i risultati globali dell’iniezione

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

138

37c __vector_15 0 8 0 0

328 __vector_15 6 2 0 0

520 __vector_15 6 2 0 0

1c9a main 0 0 8 0

1efe main 0 0 8 0

Anche in questo caso nella tabella sono riportate le locazioni utilizzate in tutte le diverse

tipologie di iniezione, in particolare vale il principio di classificazione descritto nel

paragrafo precedente.

Di seguito riportiamo il grafico che contiene la percentuale di occorrenza per gli errori di

tipo Crash ed Hang al variare dei cicli di latenza riscontrati.

Se confrontiamo questo grafico con quello di figura 5.24 (grafico della latenza totale

relativa agli esperimenti di fault injection sull’applicazione Blink di TinyOS) notiamo una

minore variabilità dei cicli di latenza ed anche una loro riduzione sia per gli errori di tipo

Tabella 5.13: Parametri globali utilizzati per la campagna di fault injection e outcome

Figura 5.28: Latenza globale

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

139

Crash che per quelli di tipo Hang. Tuttavia i risultati ottenuti non possono essere ritenuti

significativi a causa del ridotto numero di esperimenti di fault injection eseguiti.

5.4 TinyOS vs Mantis OS

In base ai risultati ottenuti attraverso la campagna di fault injection possiamo mettere in

evidenza alcune caratteristiche dei due sistemi operativi.

Iniziamo confrontando due moduli simili dei due sistemi operativi: il dispatcher di Mantis

e lo scheduler di TinyOS. Di seguito riportiamo una tabella che contiene le percentuali di

occorrenza degli errori che sono stati riscontrati durante gli esperimenti di fault injection

concentrati in questi due moduli.

Hang Error Crash Error Errori latenti Errori da

approfondire

Dispatcher

(Mantis)

0,0% 17,2% 69,0% 13,8%

Scheduler

(TinyOS)

38,2% 55,6% 0,0% 6,2%

In base ai valori della tabella possiamo dire che il dispatcher di Mantis OS è più robusto

rispetto allo scheduler di TinyOS anche se quest’ultimo è in un certo senso più “safe” visto

che la percentuale degli errori di tipo Crash è tre volte superiore.

Riportiamo di seguito i risultati ottenuti effettuando un’analisi analoga su due coppie di

procedure simili: mos_mutex_lock e mos_mutex_unlock di Mantis OS e nesc_atomic_star

e nesc_atomic_end di TinyOS.

Tabella 5.14: Percentuali errori per il confronto tra scheduler e dispatcher

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

140

Hang Error Crash Error Errori latenti Errori da

approfondire

mos_mutex_lock

mos_mutex_unlock

0,0% 96,9% 3,1% 0,0%

nesc_atomic_start

nesc_atomic_end

38,7% 42,5% 0,0% 18,8%

In base ai valori della tabella possiamo affermare che, relativamente all’iniezione dei fault

nelle due coppie di procedure, Mantis è in un certo senso più “safe” di TinyOS (infatti la

percentuale di occorrenza degli errori di tipo Crash in Mantis è doppia rispetto a quella di

TinyOS) ed anche più robusto in quanto si sono verificati alcuni casi di errori latenti.

Inoltre se consideriamo l’iniezione nel registro SP, notiamo che in Mantis OS abbiamo il

62,1% di errori di tipo Crash con solo il 5,7% di errori di tipo Hang mentre in TinyOS

abbiamo il 57,3% di errori di tipo Hang con il 39% di errori di tipo Crash. Questo

comportamento è causato dalla differente struttura dei due sistemi operativi, in particolare

essendo Mantis un sistema operativo multithread associa uno stack ad ogni thread

effettuando dei controlli sui suoi limiti, quindi l’iniezione di un fault nel registro SP spesso

porta a violare i limiti impostati allo stack generando un errore di tipo Crash. Un altro

punto a favore di Mantis OS è la minore latenza degli errori relativi alla fault injection in

memoria, infatti in questo modo è possibile sia bloccare in anticipo l’esecuzione

dell’applicazione riducendo il consumo energetico del sensore e sia permettere ad un

eventuale detector di intervenire più tempestivamente. Tuttavia un punto a favore di

TinyOS è la minore percentuale di errori da approfondire, infatti questa tipologia di errori

richiede per l’interpretazione un’elaborazione aggiuntiva. In particolare gli errori da

approfondire possono provocare malfunzionamenti di natura diversa: di valore (ad

esempio accensione di un led sbagliato oppure invio di una misurazione errata), di

omissione (ad esempio il mancato invio di un messaggio) e bizantini. Di seguito come

Tabella 5.15: Percentuali errori per il confronto tra coppie di procedure

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

141

caso notevole riportiamo due errori da approfondire (uno relativo a TinyOS e l’altro a

Mantis OS) che hanno provocato un malfunzionamento di valore (sequenza di accensione

dei led sbagliata).

Per l’applicazione blink_led di Mantis OS la sequenza di accensione dei led corretta,

nell’intervallo temporale di 2 secondi, è: Yellow: on Green: on Red: on Yellow: off Green: off Red: off Yellow: on Green: on Red: on Red: off Red: on Red: off Red: on Red: off Red: on Red: off Red: on Red: off

Invece per l’errore da approfondire relativo all’iniezione nel codice alla locazione 284,

otteniamo la seguente sequenza di accensione: Yellow: on Green: on Red: on Yellow: off Green: off Red: off Yellow: on Green: on Red: on Yellow: off Red: off Red: on Red: off Red: on Red: off Red: on Red: off Red: on Red: off

in cui si nota l’errato spegnimento del led giallo.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

142

Per l’applicazione blink di TinyOS la sequenza di accensione dei led corretta,

nell’intervallo temporale di 2 secondi, è: Red: on Green: on Yellow: on Red: off Green: off Yellow: off Red: on Red: off Green: on Red: on

Invece per l’errore da approfondire relativo all’iniezione in memoria alla locazione 18b4,

otteniamo la seguente sequenza di accensione: Red: on Green: on Yellow: on Red: off Green: off Yellow: off Red: on Green: on Yellow: on Red: off Yellow: off Red: on Yellow: on

in cui notiamo la non corretta accensione dei led verde e giallo.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

143

Conclusioni

Il presente lavoro di tesi nasce dall’esigenza di utilizzare l’AVR-INJECT Tool, realizzato

da Testa nel suo lavoro di tesi [9], come strumento per valutare la robustezza ai guasti di

sistemi operativi differenti. Per fare ciò c’è la necessità di automatizzare la fase di analisi

dei risultati del tool.

Il lavoro è iniziato partendo da uno studio accurato del tool che ha permesso la rilevazione

e la correzione di alcuni problemi. Successivamente sono state ampliate le sue

funzionalità, in particolare è stata introdotta la possibilità di iniettare guasti all’interno del

registro Stack Pointer (SP) ed è stato automatizzato il processo di analisi dei risultati

(questo processo in modo automatico effettua sia la classificazione che la generazione dei

grafici dei risultati).

Nella seconda parte del lavoro di tesi, il tool modificato è stato utilizzato come strumento

per la realizzazione di un’analisi comparativa tra TinyOS e Mantis.

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

144

Sviluppi futuri

Tra i possibili sviluppi futuri possiamo individuare la modifica del tool per realizzare

campagne di fault injection su sensori reali attraverso l’utilizzo dell’interfaccia JTAG.

Un altro miglioramento possibile potrebbe essere l’aggiunta di nuove tipologie di guasti

come: stuck-at e software faults.

Un altro possibile sviluppo futuro può riguardare la generazione dei parametri per lo studio

di tipo random. Infatti al momento il tool genera valori casuali seguendo una distribuzione

di tipo uniforme. L’idea è quella di introdurre anche una distribuzione gaussiana: l’utente

in tal caso dovrà fornire due parametri, media e varianza (µ, σ).

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

145

Bibliografia

[1] E. Sisinni Reti wireless di sensori: problematiche e recenti sviluppi

[2] Ruiping Ma; Liudong Xing; Michel, H.E. Fault-Intrusion Tolerant Techniques in

Wireless Sensor Networks 2nd IEEE International Symposium on Volume , Issue , Sept.

2006

[3] D. Stott, P.H. Jones, M. Hamman, Z. Kalbarczyk, R.K. Iyer NFTAPE: Networked Fault

Tolerance and Performance Evaluator University of Illinois at Urbana-Champaign

[4] Robert Slater, Fault Injection, Carnegie Mellon University, Spring 1998

[5] Jeffrey Voas, Fault Injection for the Masses, Reliable Software Technologies,

December 1998

[6] Fulvio Corno, Maurizio Rebaudengo, Matteo Sonza Reorda, Tecniche per il progetto di

sistemi elettronici tolleranti ai guasti, 15-23 luglio 2002

[7] Andrea Aiello, Tecniche software per l’iniezione di guasti su microcontrollori per reti

di sensori senza filo, luglio 2007

[8] Weining Gu, Zbigniew Kalbarczyk, Ravishankar K. Iyer, Error Sensitivity of Linux

Kernel Executing on PowerPC G4 and Pentium 4 Processors, 2004

[9] Alessandro Testa, Un tool per l’iniezione di guasti in microcontrollori per Wireless

Sensor Networks, settembre 2008

[10] Shah Bhatti, James Carlson, Hui Dai, Jing Deng, Jeff Rose, Anmol Sheth, Brian

Shucker, Charles Gruenwald, Adam Torgerson, Richard Han, MANTIS OS: An Embedded

Multithreaded Operating System for Wireless Micro Sensor Platforms, agosto 2005

[11] Filippo Pacifici, Metodologie per la realizzazione di software per reti di sensori

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

146

[12] Cormac Duffy, Utz Roedig, John Herbert, Cormac Sreenan, A Comprehensive

Experimental Comparison of Event Driven and Multi-Threaded Sensor Node Operating

Systems, marzo 2008

Valutazione mediante fault injection di sistemi operativi per reti di sensori senza filo

147

Sitografia

(1) TinyOS

http://www.tinyos.net

(2) Washington Sate University Vancouver

http://www.vancouver.wsu.edu/

(3) IBM JDK

http://www.ibm.com/developerworks/java/jdk/

(4) Avrora

http://compilers.cs.ucla.edu/avrora/

(5) Eclipse

http://www.eclipse.org/

(6) Xerces

http://xerces.apache.org/

(7) Mantis

http://mantis.cs.colorado.edu/