Tesi - DEI
Transcript
Tesi - DEI
Università degli Studi di Padova Facoltà di Ingegneria Tesi di Laurea Sincronizzazione Temporale in reti di Sensori Wireless Relatore: Ch.mo Prof. Luca SCHENATO Laureando: Alessio BASSO CORSO DI LAUREA IN INGEGNERIA INFORMATICA ANNO ACCADEMICO 2004-2005 Alla mia famiglia al Nonnno e alla Nonna Indice Abstract vii 1 Introduzione 1 1.1 Reti di sensori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Network Time Protocol . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Standard di Tempo e Frequenza . . . . . . . . . . . . . . . . . . . . 5 1.4 La definizione di secondo . . . . . . . . . . . . . . . . . . . . . . . . 6 1.5 Metodi standard per trasferire il tempo . . . . . . . . . . . . . . . 8 1.6 Metodi per aggirare il problema . . . . . . . . . . . . . . . . . . . . 10 1.6.1 Virtual Time . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.6.2 Localizzazione Spaziale senza sincronizzazione . . . . . . . . 10 2 Perché la sincronizzazione 2.1 13 Integrazione dei dati provenienti da più sensori . . . . . . . . . . . 14 2.1.1 Approccio di tipo brute force . . . . . . . . . . . . . . . . . 15 2.1.2 Necessità di approcci migliori . . . . . . . . . . . . . . . . . 15 2.2 In-Network Processing . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.3 Azione Coordinata . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 Radio Scheduling efficente . . . . . . . . . . . . . . . . . . . . . . . 18 2.5 Localizzazione per mezzo di segnali acustici . . . . . . . . . . . . . 19 2.6 Array Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.7 Usi in sistemi distribuiti tradizionali . . . . . . . . . . . . . . . . . 21 2.8 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3 Caratteristiche del clock 3.1 23 Modello del clock . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.1.1 25 Software clock . . . . . . . . . . . . . . . . . . . . . . . . . ii INDICE 3.2 Metriche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.2.1 Errore di Fase . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.2.2 Errore di Frequenza . . . . . . . . . . . . . . . . . . . . . . 26 3.2.3 Validità temporale (lifetime) . . . . . . . . . . . . . . . . . 27 3.2.4 Validità spaziale (scope) . . . . . . . . . . . . . . . . . . . . 28 3.2.5 Disponibilità . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.2.6 Interno/Esterno . . . . . . . . . . . . . . . . . . . . . . . . 29 3.2.7 Consumo energetico . . . . . . . . . . . . . . . . . . . . . . 30 3.2.8 Tempo di convergenza . . . . . . . . . . . . . . . . . . . . . 31 3.2.9 Costo e dimensioni . . . . . . . . . . . . . . . . . . . . . . . 31 3.2.10 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4 Alle basi della sincronizzazione 4.1 4.2 4.3 4.4 Le tecniche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.1.1 Stimare le differenze dei clock . . . . . . . . . . . . . . . . . 33 4.1.2 Periodicità . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Combinare i risultati . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.2.1 Regressione lineare . . . . . . . . . . . . . . . . . . . . . . . 37 4.2.2 Phase-locked Loop . . . . . . . . . . . . . . . . . . . . . . . 39 4.2.3 Convex-hull [9] . . . . . . . . . . . . . . . . . . . . . . . . . 39 Trattare gruppi di nodi . . . . . . . . . . . . . . . . . . . . . . . . 39 4.3.1 Sincronizzazione esterna . . . . . . . . . . . . . . . . . . . . 40 4.3.2 Clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 4.3.3 Alberi di copertura . . . . . . . . . . . . . . . . . . . . . . . 41 4.3.4 Non strutturata . . . . . . . . . . . . . . . . . . . . . . . . . 41 Fonti di ritardo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.4.1 47 Analisi degli errori . . . . . . . . . . . . . . . . . . . . . . . 5 Tecniche di stima di skew e drift 5.1 5.2 33 53 Correggere le proprie letture . . . . . . . . . . . . . . . . . . . . . . 54 5.1.1 Definizioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 5.1.2 Sample repository . . . . . . . . . . . . . . . . . . . . . . . 55 5.1.3 Fit polinomiale . . . . . . . . . . . . . . . . . . . . . . . . . 56 5.1.4 Resincronizzazione periodica . . . . . . . . . . . . . . . . . 57 Calcolare il periodo di campionamento . . . . . . . . . . . . . . . . 58 5.2.1 58 Modello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE iii 5.2.2 Numero di campioni . . . . . . . . . . . . . . . . . . . . . . 59 5.2.3 Periodo di campionamento . . . . . . . . . . . . . . . . . . 59 5.2.4 Time Window . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.2.5 Errore della predizione . . . . . . . . . . . . . . . . . . . . . 61 5.2.6 Accuratezza della stima . . . . . . . . . . . . . . . . . . . . 62 5.2.7 Fattore di scala . . . . . . . . . . . . . . . . . . . . . . . . . 64 5.2.8 Calcolo dei parametri a runtime . . . . . . . . . . . . . . . 65 6 Algoritmi di sincronizzazione 67 6.1 Come valutare le prestazioni . . . . . . . . . . . . . . . . . . . . . . 67 6.2 LTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 6.2.1 Prestazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 RBS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 6.3.1 Single-hop . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 6.3.2 Multi-hop . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 6.3.3 Prestazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 TPSN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 6.4.1 Level discovering . . . . . . . . . . . . . . . . . . . . . . . . 73 6.4.2 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . 74 6.4.3 Prestazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 FTSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 6.5.1 Single-hop . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 6.5.2 Multi-hop . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 6.5.3 Prestazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Average Timesync . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 6.6.1 Modello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 6.6.2 Algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Esperimenti effettuati . . . . . . . . . . . . . . . . . . . . . . . . . 81 6.7.1 Accuratezza dell’oscillatore al quarzo . . . . . . . . . . . . . 81 6.7.2 Deriva dei clock a 32Khz . . . . . . . . . . . . . . . . . . . 82 6.7.3 Deriva dei clock a 1Mhz (DCO) . . . . . . . . . . . . . . . . 83 6.7.4 FTSP 32Khz . . . . . . . . . . . . . . . . . . . . . . . . . . 86 6.7.5 FTSP 1Mhz . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 6.7.6 Average 32Khz . . . . . . . . . . . . . . . . . . . . . . . . . 92 6.8 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 6.9 Sviluppi futuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 6.3 6.4 6.5 6.6 6.7 iv INDICE Appendici: 94 A Calibrazione 95 A.1 La sincronizzazione è una calibrazione . . . . . . . . . . . . . . . . 95 A.2 La calibrazione nelle sensor network . . . . . . . . . . . . . . . . . 96 A.3 Calibrazione continua del DCO . . . . . . . . . . . . . . . . . . . . 97 B TEP102: Timers 103 Bibliografia 117 Computer science is no more about computers than astronomy is about telescopes. .......... (E. W. Dijkstra) Abstract Uno degli aspetti più caratteristici dell’innovazione tecnologica del nostro tempo è sicuramente la diffusione di apparecchiature miniaturizzate, che comunicano via radio e che agiscono in maniera collaborativa ed autonoma, cioè senza intervento umano; ormai quasi tutti gli aspetti della nostra vita, quasi tutte le apparecchiature che utilizziamo, quasi tutti gli ambienti in cui lavoriamo o viviamo contengono un numero impressionante di sensori, computer, microcontrollori e software che permette di creare quelli che comunemente sono noti come smart environments. Le ragioni di questa ubiquità sono le più disparate, dalla necessità di automatizzare il maggior numero possibile di dispositivi, per rendere meno faticose e più semplici le attività quotidiane, alla necessità di monitorare i dispositivi stessi, le macchine, gli ambienti in cui si vive per avere un maggior controllo su di essi. In questo senso si è giunti ad un punto di non ritorno, è cioè talmente diffusa l’idea che di una stanza, di una macchina, di un ambiente si possano tenere sotto controllo vari parametri, che molte applicazioni e dispositivi si basano su questo assunto e lo danno per scontato, ad esempio i sistemi di riscaldamento degli edifici contano sul fatto che siano disponibili misure di temperatura di ciascuna stanza, i sistemi di irrigazione del giardino si basano su misure di umidità del terreno, i sistemi di videosorveglianza si basano su immagini di reti di telecamere wireless o su sensori di prossimità, ecc. In questa evoluzione ha giocato un ruolo importante la possibilità di raccogliere questi dati ambientali tramite dispositivi miniaturizzati, funzionanti a batteria, che non richiedono intervento umano se non per il posizionamento, dopodichè funzionano in maniera autonoma, gestendo autonomamente la raccolta dei dati, la loro aggregazione e la trasmissione alla base station che si occupa di elaborarli. Tali dispositivi sono noti come motes, e le reti con essi create come Wireless Sensor Networks. Dalla gestione di un sistema di videosorveglianza, al tracking di oggetti in mo- viii Abstract vimento, al monitoraggio di un bosco per prevenire gli incendi, al monitoraggio di strutture quali ponti e grattacieli per prevenire crolli o cedimenti strutturali, alla triangolazione della posizione di cecchini in un ambiente urbano sulla base del rumore dello sparo, al monitoraggio delle funzioni vitali di pazienti non ospedalizzati, che dunque continuano la loro vita normale, andando al lavoro o al parco, molteplici sono le applicazioni di queste tecnologie. È come avere un occhio che vede e un orecchio che sente su un’area molto vasta, ma allo stesso tempo su ogni minima porzione di quell’area, mantenendo sia una visione d’insieme della situazione sia una visione particolareggiata dei dettagli. Oltre agli innumerevoli vantaggi portati da queste infrastrutture distribuite, sono sorti anche dei probemi pratici, dal momento che molte delle soluzioni tecnologiche finora utilizzate non sono adatte all’utilizzo nelle Wireless Sensor Network. Sono dunque state elaborate versioni particolari di algoritmi di routing, di costituzione di reti wireless ad-hoc per la trasmissione dei dati, sistemi di aggregazione dei dati misurati, sistemi di fault-tolerance che permettono alla rete di continuare a funzionare anche in caso di malfunzionamento di uno o più nodi, sistemi di ottimizzazione del consumo energetico in modo che le batterie dei singoli nodi possano durare anche anni, ottenendo cosi di fatto una rete che richiede manutenzione nulla. Una parte importante di queste infrastrutture è la sincronizzazione, ovvero la capacità di tutti i nodi di mantenere una scala temporale comune. Questo è necessario per correlare misurazioni fatte da nodi diversi molto distanti tra di loro, per effettuare tracking di una persona che si muove e che viene “seguita” man mano dal nodo più vicino, per misurare distanze mediante triangolazione dei tempi di arrivo di un segnale, radio o sonoro, per la gestione coordinata di attuatori in applicazioni di controllo di macchinari in fabbrica, o di apparecchiature elettroniche nelle applicazioni di domotica. Sfortunatamente, nonostante i requisiti di precisione e accuratezza siano stringenti, le risorse disponibili — in termini di capacità computazionale, memoria e capacità di trasmissione — per soddisfare questi requisiti sono tipicamente molto più limitate in una Wireless Sensor Network che in una rete tradizionale. Necessità di minimizzare le comunicazioni radio per allungare la durata della batteria, presenza di componentistica non di precisione, in particolare per gli oscillatori, dovuta alla necessità di abbattere il costo del dispositivo, sono altre limitazioni con le quali dovremo confrontarci. ix Andremo dunque ad analizzare le soluzioni già presenti in letteratura, in maniera da individuarne i punti di forza e le manchevolezze, il campo applicativo (in base alle richieste e alle limitazioni di alcune applicazioni “classiche” di Wireless Sensor Networks), e proporremo una soluzione che tenta di coniugare i pregi e i difetti delle soluzioni più diffuse. Letteratura esistente Le soluzioni per la sincronizzazione di reti di dispositivi appartengono sostanzialmente a due diverse classi, quelle che lavorano su coppie di nodi (Pairwise) e quelle che considerano la rete in generale e il broadcast come sistema di trasmissione delle informazioni di sincronizzazione (Flooding). Pairwise La sincronizzazione viene effettuata tramite scambi di pacchetti tra coppie di nodi: ciascun nodo manda un messaggio contenente una lettura del suo clock (timestamp); il nodo ricevente prende nota dell’istante di ricezione del pacchetto, e riesce cosı̀ costruire una relazione tra il suo clock e quello del nodo che ha spedito il pacchetto, sapendo che Tr = Ts + Tttf (dove Tr è l’istante di ricezione del pacchetto, Ts quello di spedizione, e Tttf è il time-to-flight, ovvero il tempio impiegato dal pacchetto per giungere dal nodo trasmittente al nodo ricevente). Spesso la misurazione di questo tempo di viaggio viene effettuata grazie ad un terzo nodo che fa da riferimento per le misurazioni. Il vantaggio di questo sistema è che, tramite il confronto delle misurazioni reciproche dei due nodi, si riescono ad eliminare molte delle incertezze nella catena di trasmissione e ricezione dei pacchetti. Lo svantaggio è che in reti con molti nodi si deve sincronizzare ciascuna coppia di nodi, il che porta ad un tempo di convergenza molto alto per l’algoritmo e genera un traffico di rete molto elevato. Sono state sviluppate delle varianti di questo approccio che costruiscono prima una topologia della rete, e la usano per ridurre il numero di sincronizzazioni pairwise effettuate: ciascun nodo si sincronizza solo con i genitori e il figli nell’albero che rappresenta la rete. Questo approccio velocizza al convergenza e riduce l’overhead, ma è meno robusto perché la topologia dev’essere ricostruita in caso si spostamento o spegnimento di un nodo, che avvengono frequentemente nelle applicazioni reali. Algoritmi di questo tipo sono [12, 13, 19] e [29]. x Abstract Flooding La trasmissione delle informazioni di sincronizzazione viene effettuata tramite broadcast. Ogni nodo riceve le letture del clock di un nodo particolare, detto radice, e tenta di capire “quanto più veloce” o “quanto più lento” va il suo clock locale rispetto a quello della radice, in maniera da poter calcolare con una certa approssimazione, a partire dal tempo segnato dal suo clock locale, il tempo segnato dal clock del nodo radice. I vantaggi sono che la trasmissione broadcast annulla i ritardi dovuti ai meccanismi di routing, cioè tutti i nodi nell’intervallo di broadcast ricevono i messaggi praticamente nello stesso istante. Inoltre ciascun nodo continua a “inseguire” il tempo del nodo radice e quindi la sincronizzazione è sempre abbastanza precisa. Gli svantaggi sono la necessità che tutti i nodi siano nell’intervallo di broadcast del nodo radice, pena ritrasmissioni che innalzano necessariamente l’errore di sincronizzazione, e al dipendenza della consistenza del tempo della rete dal nodo radice: anche se esistono vari meccanismi che provano ad ovviare, di norma se il nodo radice si spegne la rete va fuori sincronia per un certo periodo di tempo. Un algoritmo di questo tipo è [24]. Un’ulteriore contributo fondamentale, che si muove in parallelo al nostro lavoro, è il paper di Ganeriwal e altri [32] sulla caratterizzazione dell’errore di predizione, in cui si da un modello dell’errore nella predizione del valore del clock che viene fatta da ciascun nodo, modello che viene utilizzato per la determinazione a runtime dei parametri funzionali dell’algoritmo, quali il periodo di campionamento delle misurazioni effettuate per la stima dell’errore. Si riesce cosı̀ a calcolare l’intervallo ottimo di resincronizzazione, cioè a massimizzare il tempo in cui il nodo sta senza effettuare operazioni di sincronizzazione; questo si traduce in un risparmio energetico, perché la sincronizzazione richiede scambi di pacchetti e quindi trasmissioni radio, e in un alleggerimento del carico della rete, che invece di sincronizzarsi può essere usata per la raccolta dei dati e per la loro eventuale trasmissione verso la base station. Contributo Scopo di questo lavoro è l’analisi e l’implementazione di algoritmi per mantenere in sincronia gli orologi di vari nodi di una rete di sensori wireless. Una Wireless Sensor Network è una rete costituita da piccoli dispositivi composti da più sensori di vario tipo, un microprocessore, una memoria e un trasmettitore a radiofrequenza [15]. xi Abbiamo cercato soluzioni per adattare uno degli algoritmi più robusti presenti in letteratura, FTSP [24], a reti di motes del modello moteiv tmote sky, analizzando la deriva dei clock di questi sensori e creando un modello che permettesse di compensare, sul breve periodo, per questo errore. FTSP richiede un clock la cui deriva sia sostanzialmente monotona, quindi le correzioni applicate vanno in tal senso. Abbiamo inoltre proposto un nuovo algoritmo, che abbiamo chiamato Average Timesync, basato su una sorta di “condivisione” tra i nodi della rete dei parametri per la stima dell’errore del clock: i nodi sostanzialmente si accordano su un valore medio da utilizzare. FTSP su tmote sky Il Flooding Time Synchronization Protocol è un protocollo di sincronizzazione proposto per la prima volta da Maroti e altri nel 2004 ed implementato sulla piattaforma mica2 verso la metà del 2005. Si basa sul principio che i nodi sincronizzati “inseguono” il tempo dettato da un nodo radice cercando di stimare qual’è la deriva del loro clock locale rispetto a quello del nodo radice. Per fare questo si assume che il clock utilizzato abbia skew monotono, cosa vera per la piattaforma mica2 utilizzata nell’implementazione degli autori. Il contributo di questo lavoro in tal senso è stato verificare la rispondenza alle ipotesi delle due sorgenti di clock disponibili nel tmote sky — l’oscillatore al quarzo esterno a 32khz e il DCO (digital controlled oscillator) interno — e risolvere i conflitti causati dalla routine di calibrazione continua del DCO stesso, che nel tentativo di sincronizzare il DCO con l’oscillatore al quarzo causava delle fluttuazioni casuali del clock stesso di entità non trascurabile. Successivi test con le due sorgenti di clock sopracitate confermano il funzionamento dell’algoritmo anche sulla nuova piattaforma, con margini di errore paragonabili a quelli in letteratura, ovviamente tenendo conto della minor frequenza dei clock usati. In particolare interessava verificare il funzionamento con l’oscillatore al quarzo a 32khz, nell’ottica di una sincronizzazione power-saving che utilizza quanto meno possibile il microcontrollore. Average L’algoritmo proposto in questa tesi mira a risolvere il “punto debole” del FTSP, cioè la dipendenza da un nodo radice che fa da riferimento per la sincronizzazione. Nell’Average Timesync il tempo di riferimento non è dato da un clock reale ma da un virtual clock, definito tramite l’uso di un valore medio di skew comune a tutti i nodi della rete. In questo modo il parametro per la correzione dei clock dei nodi è disponibile in tutta la rete, e nel caso di spegnimento di un singolo xii Abstract nodo la sincronizzazione non deve ripartire da zero. I test hanno confermato che gli errori di sincronizzazione ottenuti sono in linea con quelli visti per FTSP. Contenuti dell’elaborato Di seguito verranno esposti in breve i contenuti dei singoli capitoli. Capitolo 1 Questo capitolo introduce brevemente il concetto di Wireless Sensor Network, le applicazioni per ll quali viene tipicamente utilizzata, e quali sono le caratteristiche (e le limitazioni) peculiari che la differenziano da altri tipi di reti wireless. Vengono inoltre presentate le tecniche e le terminologie standard per la misurazione del tempo, e per il trasferimento di misure temporali nell’ottica di minimizzare gli errori introdotti nel trasferimento. Infine si introduce il Network Time Protocol, un protocollo standard per la sincronizzazione in reti tradizionali cablate, e altri metodi che forniscono una scala temporale ben definita evitando però la sincronizzazione esplicita dei nodi. Capitolo 2 In questo capitolo vengono presentate varie applicazioni di Wireless Sensor Network che necessitano di una sincronizzazione esplicita della rete. In particolare ci si sofferma sull’uso della sincronizzazione per migliorare le performance della rete (radio scheduling efficente, data aggregation e in-network processing dei dati rilevati,...), oltre a presentare applicazioni che si basano per il loro funzionamento sulla sincronizzazione stessa (acoustic ranging e coordinated actuation). Capitolo 3 In questo capitolo si introduce un modello matematico del clock, in maniera da poter analizzare quali sono le restrizioni imposte da questo modello e quali possono essere delle metriche efficaci per valutare le prestazioni degli algoritmi di sincronizzazione. Alcune di queste metriche si soffermano sulla valutazione delle prestazioni del clock stesso (errori di frequenza e fase), altre invece su parametri propri della rete, quali scope e disponibilità della scala temporale, consumo energetico e costo di realizzazione. Capitolo 4 Si introducono in questo capitolo metodi per leggere con precisione il valore del clock di un nodo remoto, e si introduce l’uso di misure ripetute per xiii migliorare la precisione di queste letture, sia statisticamente che analiticamente. Si estendono poi queste procedure a reti di più di due nodi, analizzando varie tecniche per la gestione della rete stessa. Infine si effettua una analisi approfondita della catena di trasmissione di un pacchetto tra due nodi di una Wireless Sensor Network, al fine di individuare tutte le possibili fonti di errore e di incertezza; si prendono in esame i due approcci sender-receiver e receiver-receiver e si discutono i vantaggi e gli svantaggi di ciascuna. Capitolo 5 In questo capitolo si introduce un modello per il lo skew, e si descrive il suo utilizzo per la stima che un nodo fa del clock di un nodo remoto. In base all’errore su questa stima, di cui viene data una estesa caratterizzazione statistica, si presentano alcune tecniche per ottimizzare i parametri caratteristici del modello in un’ottica power-saving. Capitolo 6 In questo capitolo vengono presentati gli algoritmi di sincronizzazione più diffusi in letteratura, RBS, TPSN e FTSP, e l’algoritmo da noi proposto, Average Timesync. Per ciascuno si descrive il funzionamento di base, si da una caratterizzazione degli errori di cui al Capitolo 4, sottolineando per quali di essi gli effetti vengono annullati o minimizzati tramite particolari tecniche. Si presentano infine i risultati degli esperimenti da noi condotti sulle derive degli oscillatori dei tmote sky e sulle prestazioni dell’algoritmo proposto, Average Timesync, rispetto al Flooding Timesync. xiv Abstract Capitolo 1 Introduzione Che cosa è, allora, il tempo? Se nessuno me lo chiede, lo so; se dovessi spiegarlo a chi me ne chiede, non lo so. Sant’Agostino In questo capitolo verrà brevemente presentato il concetto di rete di sensori (sensor network), le sue caratteristiche e le limitazioni peculiari. Presenteremo una panoramica delle tecnologie allo stato dell’arte nel mantenimento e nella trasmissione del tempo, e concluderemo con l’analisi di tre sistemi di radiolocalizzazione che aggirano il problema della sincronizzazione dei disposiivi. 1.1 Reti di sensori I recenti sviluppi tecnologici hanno permesso la progettazione e realizzazione di componenti sempre più piccoli e che consumano sempre meno energia [18] [20] e [14]. Molti ricercatori sostengono che sia possibile creare degli “ambienti intelligenti” distribuendo in questi ultimi moltissimi chip, capaci di elaborazione e trasmissione radio, ai quali sono collegati sensori capaci di rilevare condizioni locali quali temperatura, umidità, rumore, luce, movimento di oggetti o presenza di sostanze chimiche. Per queste reti di sensori sono state pensate moltissime applicazioni, quali ad esempio monitoraggio ambientale climatico [8, 7], controllo e manutenzione di macchine utensili, prevenzione di crolli di edifici, rilevazione della posizione di cecchini in ambiente urbano [17], monitoraggio continuo di pazienti [34], e molte altre. Molto spesso per il monitoraggio si usano reti di pochi sensori con raffinate capacità di sensing e di trasmissione radio a lungo raggio, ma questo non permette 2 Introduzione di rilevare tutti gli eventi se essi sono distribuiti su un’area molto grande. Un approccio migliore può dunque essere quello di distribuire un grandissimo numero di sensori nell’ambiente da monitorare, ma in questo caso diventa proibitivo realizzare le classiche infrastrutture di comunicazione e alimentazione elettrica dei sensori stessi. E’ in questo campo che le reti di sensori wireless ci vengono in aiuto, permettendo di osservare l’ambiente in maniera fondamentalmente differente dalle precedenti classi di sistemi, e cioè nelle vicinanze dei fenomeni in oggetto, su una larga area, e con alta densità sia nel tempo che nello spazio. Il progetto di queste reti di sensori è fondamentalmente diverso da quelle tradizionali. Uno delle differenze più evidenti riguarda il consumo di energia. Per facilitare la messa in opera della rete, i nodi sono necessariamente alimentati a batteria, quindi con un periodo di vita limitato. A differenza dei comuni dispositivi a batteria però, molto spesso ai nodi di una sensor network le batterie non possono essere cambiate, perché si trovano in luoghi inaccessibili ad un operatore umano, e perché numero elevato di sensori che cosituiscono la rete renderebbe troppo onerose queste operazioni di manutenzione. Il consumo di energia di un nodo è in gran parte dovuto alla comunicazione radio con gli altri nodi, che deve quindi essere ridotta il più possibile: per questo nelle reti di sensori si prediligono le elaborazioni locali ai nodi e si fa largo uso di tecniche di aggregazione dei dati in modo da evitare di trasmettere tutte le rilevazioni per una successiva elaborazione, ma solo i dati aggregati di interesse. Le reti di sensori devono inoltre essere dinamiche: molti nodi possono spegnersi, per mancanza di energia, perché surriscaldati dal sole, per malfunzionamenti software, portati via dal vento o da un animale. Anche se rimangono in posizione, la portata delle comunicazioni radio di un nodo (e dunque la topologia della rete) può variare di molto in base alle condizioni ambientali. Questi cambiamenti non sono prevedibili a priori, e mentre nelle reti tradizionali tali problemi vengono risolti con l’intervento di un operatore, nelle sensor network ciò non è possibile. Esse devono essere dunque autoconfiguranti e autoadattanti ai cambiamenti nell’ambiente. Solitamente in una rete di sensori si distinguono due livelli separati, uno dedicato all’acquisizione dei dati e uno alla loro distribuzione e consultazione. Sebbene questa suddivisione sia logicamente accettabile e utile, nella pratica, come in molti sistemi embedded, i due livelli si fondono l’uno con l’altro, integrando in un’unica infrastruttura hardware/software tutte le funzionalità richieste dall’applicazione per cui la Sensor Network è stata progettata. La Figura 1.1 mostra 1.2 Network Time Protocol 3 tale suddivisione e cita alcune delle tecnologie e dei campi applicativi in cui sono utilizzate. Figura 1.1: Suddivisione “logica” di una Wireless Sensor Network: Data Acquisition e Data Distribution 1.2 Network Time Protocol Esistono vari protocolli per la sincronizzazione dei clock di una rete di calcolatori. Questi hanno molte caratteristiche in comune: un semplice protocollo di comunicazione non orientato alla connessione, lo scambio di informazioni sul clock tra i client e uno o più server, metodi per limitare il non determinismo del tempo di propagazione ed elaborazione dei messaggi, e un algoritmo per aggiornare il clock dei client in base alle informazioni ricevute dal server; differiscono invece in alcun dettagli, se ad esempio il tempo della rete è consistente solo all’interno della rete stessa o se è sincronizzato con un riferimento esterno, se il server che da il riferimento temporale è un dispositivo a parte oppure uno dei nodi, eccetera. Molti di questi protocolli, alle caratteristiche comuni descritte sopra, aggiungono vari metodi per migliorare le prestazioni, ad esempio una migliore rilevazione dei 4 Introduzione campioni spuri (outlier), riduzione dello jitter (non-determinismo), mantenimento della sincronizzazione anche nel caso di spegnimento di uno o più nodi. Ad esempio: • Cristian [11] ha osservato che lo scambio ripetuto di sequenze di pacchetti di richiesta/risposta rende alta la probabilità che una di esse non risenta pesantemente dei ritardi non deterministici dovuti alla trasmissione e all’elaborazione del pacchetto stesso. Il tempo di andata e ritorno della sequenza in oggetto può dunque essere considerato il più piccolo round-trip time. • Marzullo e Owicki [22] hanno descritto un algoritmo che produce una stima corretta del tempo a partire dalle informazioni di n timeserver, anche nel caso di malfunzionamento di n/2 dei server. • Mills [26] ha sviluppato un controllore per disciplinare la frequenza di un oscillatore in maniera che essa coicida con una sorgente di clock esterna sia in fase che in frequenza. Il protocollo più usato è conosciuto come Network Time Protocol, o NTP [25], ed è quello che si è rivelato più efficiente in termini di scalabilità, autoconfigurabilità in reti multi-hop, robustezza e resistenza al sabotaggio (tentativi volontari di alterare il tempo della rete usando un client o un timeserver). NTP costruisce una gerarchia di timeserver, ciascuno dei quali può far riferimento ad una sorgente esterna di clock, ad esempio un orologio molto preciso o un ricevitore gps. Si è evoluto molto nei trent’anni in cui è in uso, incorporando molte delle idee che di volta in volta sono state proposte dai ricercatori, incluse le tre di cui abbiamo parlato poche righe fa. Altri sistemi sono il CesiumSpray [28], descritto da Verı̀ssimo e Rodrigues, e la sincronizzazione basata su broadcast descritta da Mock in [23]. Questi sistemi utilizzano la proprietà della trasmissione broadcast di giungere a tutti i nodi destinatari praticamente nello stesso istante per ottenere maggior precisione, e quindi compensare per alcuni dei ritardi di cui andremo a parlare in maniera più dettagliata nel capitolo 4. Purtroppo, questi sistemi prevedono che tutti i nodi da sincronizzare siano raggiungibili tra di loro tramite una trasmissione broadcast, cosa che in reti estese non è sempre possibile. Molti algoritmi, tra cui RBS proposto da Jeremy Elson [13, 19, 12] e FTSP di Miklòs Maròti e Brano Kusy [24], permettono di sincronizzare anche nodi di una rete multihop, anche se in questo 1.3 Standard di Tempo e Frequenza 5 caso la precisione ottenuta degrada all’aumentare del numero di hop che separano il nodo in questione dal nodo che fa da riferimento per la sincronizzazione. 1.3 Standard di Tempo e Frequenza Abbiamo descritto poc’anzi schemi che mirano a sincronizzare in qualche modo il clock di una serie di nodi. E’ implicitamente assunta l’esistenza di un clock locale in ciascun nodo. Un clock è un contatore di eventi che indicano il passaggio di un determinato intervallo temporale (ad esempio 1 secondo), ed etichetta in maniera univoca ciascuno di questi intervalli. Questi eventi sono generati da un riferimento di frequenza che si basa sull’osservazione di un qualche processo periodico, ad esempio il transito del sole lungo un meridiano, la vibrazione di un cristallo di quarzo, il battito di un pendolo, la frequenza della radiazione emessa da un atomo di cesio. La qualità di un clock dipende dalla sua stabilità in frequenza, ovvero al capacità del riferimento scelto di emettere gli eventi con una frequenza stabile nel tempo. Il fatto che l’intervallo di tempo tra un evento e l’altro, ovvero il reciproco della frequenza, coincida con l’intervallo desiderato (accuratezza) è anch’esso importante, ma con la calibrazione si può facilmente ovviare a riferimenti stabili ma non accurati. Gli errori ottenibili nella sincronizzazione di due clock sono direttamente legati, oltre che al metodo di sincronizzazione, alla qualità dei clock, e quindi alla stabilità della loro frequenza. Un clock stabile riesce a compensare gli errori (non sistematici) introdotti da un canale rumoroso, mediando molte misurazioni prese su un lungo periodo di tempo. Similmente, un canale di trasmissione molto preciso può compensare per clock poco stabili, ripetendo spesso le operazioni di sincronizzazione e riducendo dunque il tempo in cui il clock è lasciato libero di derivare. Esistono molti tipi di riferimenti di frequenza. In genere, al crescere della stabilità e accuratezza aumentano anche costo, dimensioni e consumo energetico, fattori cruciali in una sensor network. Dispositivi molto diffusi sono i comuni oscillatori al quarzo (caratterizzati in [35]), molto usati perché sono poco costosi, consumano pochissima energia e sono relativamente molto stabili. La frequenza generata da un tale oscillatore è soggetta a variazioni causate da molti fattori: voltaggio applicato, temperatura, accelerazione, campi magnetici, . . . . Altre va- 6 Introduzione riazioni sono dovute, sul lungo periodo, a fenomeni di aging, cioè variazioni interne della struttura dell’oscillatore dovute al lungo uso. Gli oscillatori che si trovano nei normali PC hanno una frequenza nominale con una accuratezza pari a 104 − 106 —cioè due oscillatori uguali ma non calibrati possono differire nella frequenza segnata tra 1 e 100 microsecondi ogni secondo, oppure tra 0,1 e 10 secondi ogni giorno [12]. La loro stabilità è invece molto migliore—con variazioni della frequenza tra 109 e 1011 per ogni secondo. Ci sono molte varianti di questa tecnologia, come i temperature-compensated oscillator (TCXO), che contengono circuiti che compensano le variazioni di temperatura, oppure gli ovencontrolled oscillator (OCXO), che generano calore per mantenere l’oscillatore alla temperatura di funzionamento ottimale: solitamente però richiedono più energia, un tempo di startup più lungo, sono più ingombranti e costano di più. È verificato che gli oscillatori che pilotano i comuni processori di classe pentium hanno una bassa accuratezza ma una alta stabilità, il che li rende adatti all’uso in applicazioni di misura ad alta precisione. Il TSC di questi processori (il contatore dei cicli di istruzione), leggibile con bassa latenza, è pilotato dal clock della CPU, e quindi ha una risoluzione paragonabile al clock della CPU stessa (1 nanosecondo per un processore a 1GHz): si possono dunque mediare misurazioni di questo clock sul lungo periodo per ottenere la frequenza reale del clock e correggere quindi la sua scarsa accuratezza. I normali sistemi operativi però non sono adatti a queste misurazioni ad alta precisione, per via della gestione dello scheduling che non è normalmente orientata al realtime: in un kernel linux vanilla, ad esempio, l’intervallo di scheduling è 10 millisecondi, il che significa che se una applicazione di misurazione per qualche motivo (si muove il mouse, intervengono altri processi con maggior priorità, ecc . . . ) va in background, non ritorna in esecuzione prima di 10 millisecondi, falsando cosı̀ tutte le misurazioni effettuate. 1.4 La definizione di secondo Oltre agli oscillatori al quarzo, le sorgenti più importanti per la sincronizzazione sono gli orologi atomici. A differenza degli standard meccanici quali pendoli e cristalli di quarzo, gli orologi atomici si basano sull’osservazione di proprietà atomiche di elementi quali cesio e rubidio, che permettono precisioni impensabili da ottenere con qualsiasi standard meccanico. Lo stato dell’arte (dati aggiornati 1.4 La definizione di secondo 7 all’estate del 2005) è rappresentato dal NIST-F1 (fig. 1.4), che segna il tempo con un errore minore di 5 × 10−16 , perde cioè 1 secondo in 60 milioni di anni [2]. Questo dispositivo è un esemplare unico costruito in laboratorio, ma sono comunque disponibili orologi atomici commerciali di dimensioni minori e di precisione minore, come l’Agilent-HP 5071, che perdono circa 1 secondo ogni 162.000 anni. Figura 1.2: L’orologio atomico NIST-F1, il più stabile del mondo, sviluppato dal National Institute of Standards and Technology statunitense. Molto più dell’accuratezza, la caratteristica fondamentale di questi riferimenti temporali è la riproducibilità. Il principio di equivalenza di Einstein dice che le proprietà atomiche della materia sono le stesse in ogni luogo e in ogni momento. In altre parole, gli orologi atomici possono essere usati come standard primari, ovvero sorgenti di frequenza esatta sempre disponibili, a differenza delle consuete sorgenti che devono essere calibrate con un prototipo (si pensi alle bilance o ai metri, sorgenti di misura che devono esser calibrate con i campioni di chilo e metro conservati al Bureau International des Poids et Mesures a Sevres, in Francia). La disponibilità di questi riferimenti atomici li rende ideali per definire degli standard. Infatti il secondo, nel sistema SI, è definito come la durata di 9.192.631.770 periodi della radiazione corrispondente alla transizione tra due livelli iperfini dello stato fondamentale dell’atomo di cesio-133. Questa è stata una 8 Introduzione rivoluzione, dal momento che fino al 1967, anno cui risale questa definizione, i riferimenti di tempo erano ottenuti tramite l’osservazione del moto dei corpi celesti. Ad esempio, mezzogiorno era definito come il momento in cui il sole era esattamente perpendicolare alla superficie terrestre all’equatore, e un secondo era semplicemente 1/86400 della lunghezza media di un giorno. Gli orologi atomici al Cesio furono la prima sorgente di tempo disponibile che fosse stabile almento quanto la rotazione terrestre, ed infatti venne usata per stabilire che la lunghezza di un giorno può variare ogni giorno nell’ordine di decine di millisecondi. A seconda delle richieste dell’applicazione, nella sincronizzazione di un insieme di nodi la definizione di secondo e la disponibilità di un riferimento esterno può essere importante o meno. Spesso è infatti fondamentale che due orologi siano sincronizzati tra di loro, ma non con un riferimento assoluto, nè è importante conoscere esattamente a quale frequenza essi stanno andando (vedi 3.2.6). 1.5 Metodi standard per trasferire il tempo Le applicazioni che richiedono un riferimento temporale hanno dunque due possibilità: o si dotano di una sorgente primaria quale un orologio atomico, o usano come riferimento una grandezza generata da qualche altra parte. Spesso inoltre le applicazioni non necessitano solo della frequenza, ma anche di un riferimento assoluto, cioè sapere in che istante ci si trova (ad es. quando cadono precisamente le 12:00:00). In molti paesi è il governo che si occupa di fornire un riferimento di frequenza, e lo usa per costruire un riferimento temporale “ufficiale”. UTC ad esempio, la scala temporale più usata al mondo per applicazioni civili, è basata sulla media pesata di 200 orologi atomici sparsi in giro per il mondo, ed è calcolata al Bureau International des Poids et Mesures a Sevres, in Francia. Molti di questi laboratori svolgono attività di ricerca anche nel campo di metodi per il time transfer —cioè il trasferimento delle informazioni del riferimento di tempo e frequenza. È infatti fondamentale poter trasmettere altrove le informazioni temporali ricavate da questi orologi molto precisi, in maniera che esse vengano utilizzate per le varie applicazioni. Il trasferimento è inoltre fondamentale per il calcolo dello UTC, che come abbiamo visto poc’anzi è il risultato della media delle informazioni provenienti da molti orologi sparsi in giro per il mondo. Nel corso degli anni sono state elaborati molti metodi per trasferire il tempo. 1.5 Metodi standard per trasferire il tempo 9 I primi e più semplici sono gli orologi meccanici dotati di campane o altri segnali acustici (allo scoccare delle ore l’informazione “è la tal ora” veniva trasferita grazie al suono); nel diciottesimo secolo le capitanerie di porto erano solite innalzare una particolare bandiera alle 12 in punto, in maniera che le navi ormeggiate potessero sincronizzare i loro orologi meccanici che sarebbero stati il riferimento temporale durante la navigazione in alto mare. Negli anni venti si utilizzavano degli annunci vocali durante le trasmissioni radio, e il metodo è rimasto, sostituito prima da annunci automatizzati su canali dedicati e poi dalla trasmissione di segnali interpretabili da computer: questi ultimi sono ancora attivi al giorno d’oggi e permettono di sincronizzarsi con il riferimento UTC con un errore di una parte su 1013 . I sistemi di posizionamento satellitare si basano per il loro funzionamento sull’informazione temporale. Il più noto, il GPS, si basa sulla misurazione del tempo di trasmissione di segnali radio dai satelliti (di cui è nota la posizione) ad un ricevitore a terra; in questo caso l’offset tra il clock del ricevitore e quello della rete satellitare (e dunque il riferimento temporale assoluto) è ricavato come “effetto collaterale” dal calcolo della posizione. Dal momento che il tempo nella rete satellitare GPS è mantenuto nell’ordine di pochi nanosecondi rispetto allo UTC, il GPS stesso è il metodo ormai più diffuso per la trasmissione dell’informazione temporale. Fino al 2000 però l’informazione temporale disponibile per usi civili era volutamente degradata in maniera da non fornire accuratezze superiori a 200 nanosecondi: il sistema GPS è di origine militare e doveva infatti fornire informazioni temporali (e dunque di posizionamento) precise solo ai ricevitori militari, in maniera che il sistema non potesse essere sfruttato sul campo di battaglia anche dal nemico. La rimozione di questi disturbi—la cosiddetta selective availability—nel maggio del 2000, ha portato ad una accuratezza ottenibile con ricevitori a basso costo < 20nsec. Una evoluzione del sistema sono i metodi di two-way satellite time transfer [4], cioè metodi che permettono a due ricevitori “connessi” allo stesso satellite di ottenere informazioni sull’errore di fase relativo tra i due clock. Il metodo funziona meglio di quelli basati su una trasmissione monodirezionale, e viene infatti usato per il trasferimento delle informazioni temporali ai laboratori che calcolano l’UTC. Un esempio di questo metodo è il GPS Common View [1], che viene usato appunto per conoscere l’offset dei clock di due ricevitori GPS. Entrambi i ricevitori devono essere in vista dello stesso satellite, ricevono l’informazione temporale 10 Introduzione dal satellite e la confrontano con la fase del loro clock locale, compensando il time-of-flight del segnale con il calcolo della differenza tra il valore del clock del satellite e la sua posizione (la posizione reale del satellite è determinata dai dati orbitali contenuti in ogni trasmissione broadcast fatta dal satellite stesso). Questa tecnica non fornisce UTC ai ricevitori, ma permette di calcolare con precisione la differenza di fase tra i due clock locali dei ricevitori stessi, e si basa sul fatto che entrambi ricevono praticamente allo stesso istante la stessa informazione temporale, trasmessa in broadcast. È lo stesso principio su cui si basa il funzionamento dello schema di sincronizzazione RBS, trattato nel paragrafo 6.3: si migliora l’accuratezza eliminando l’incertezza nella trasmissione dal lato sender. 1.6 Metodi per aggirare il problema In molti casi il problema della sincronizzazione si risolve semplicemente non risolvendolo, ovvero progettando un sistema che non ha bisogno di una sincronizzazione esplicita. Presentiamo di seguito la proposta di Lamport del virtual clock, e tre sistemi di localizzazione spaziale che non necessitano di sincronizzazione temporale. 1.6.1 Virtual Time L’idea è che non sia tanto importante conoscere il momento esatto in cui un evento si verifica, ma che sia fondamentale la successione temporale, ovvero quali eventi si verificano prima di altri. Nell’articolo presentato da Lamport [21] ogni nodo ha un clock che è incrementato monotonicamente, e ogni volta che un evento viene rilevato un messaggio, contenente la misurazione e il timestamp dell’istante in cui la misurazione è effettuata, viene trasmesso. Il nodo che lo riceve avanza il proprio clock locale a un valore superiore a quello riportato nel messaggio. In questo modo si ottiene un ordinamento degli eventi, anche se non si tiene conto di quanto tempo passa tra di essi. Ovviamente questo metodo non è adatto per le applicazioni che richiedono una vera sincronizzazione. 1.6.2 Localizzazione Spaziale senza sincronizzazione Spesso la localizzazione spaziale è strettamente legata alla sincronizzazione, perché misurando il time-of-flight delle onde elettromagnetiche o di un qualche altro fenomeno, di cui sia nota la velocità di propagazione nell’aria, si riesce a risalire 1.6 Metodi per aggirare il problema 11 alla distanza tra il trasmettitore (T) e il ricevitore (R). I seguenti tre metodi usano sistemi diversi per liberarsi della necessità della sincronizzazione: • Nel metodo PinPoint si utilizza lo stesso dispositivo come trasmettitore e come ricevitore. • Nel GPS si usano altre relazioni che non siano quella temporale tra il trasmettitore e il ricevitore. • Nell’Active Bat si sincronizzano i dispositivi con un segnale molto più veloce di quello usato per determinare la distanza. Pin-Point In questo metodo si pone T=R, cioè trasmettitore e ricevitore sono lo stesso nodo. In dettaglio si usano due dispositivi, una base capace di emettere e ricevere segnali radio e un tag che funziona da “riflettore”. La base è fissata in un luogo di cui sono note le coordinate 3d nello spazio. Questa periodicamente manda dei segnali che vengono raccolti dai tag e reinviati indietro con le informazioni di identificazione del tag stesso: quest’ultima operazione è svolta con un ritardo molto basso e deterministico. Le base possono determinare la distanza come metà del tempo di andata e ritorno del segnale per la velocità di propagazione: usando più base e la velocità di propagazione delle onde elettromagnetiche si riesce a determinare la posizione della tag nello spazio tramite triangolazione. GPS Anche il sistema GPS, citato in 1.5, effettua la localizzazione misurando il timeof-flight di un segnale. In questo caso, il ricevitore è il dispositivo GPS e il sistema GPS (la costellazione dei satelliti) è il trasmettitore. Ciascun satellite ha una posizione nota rispetto a un sistema di riferimento solidale con la terra. Le orbite sono monitorate da un sistema a terra e trasmesse in broadcast insieme alle informazioni temporali dei satelliti. Se esistesse una qualche forma di sincronizzazione tra ricevitore e satelliti, sarebbe semplice misurare la distanza tra i due: un satellite manda un segnale con il timestamp dell’istante di spedizione, il ricevitore sottrae questo timestamp dall’istante di ricezione e lo moltiplica per la velocità di propagazione. Le misurazioni 12 Introduzione rispetto a tre satelliti ci danno la posizione nello spazio (X,Y,Z) come soluzione di un sistema di tre equazioni in tre incognite.1 Dal momento che non esiste nessuna sincronizzazione tra i satelliti e il ricevitore, si usano quattro satelliti invece di tre, e si risolve un sistema di quattro equazioni in quattro incognite, (X,Y,Z,T), dove T è l’offset tra il clock del ricevitore e quello del sistema GPS. È importante notare che la sincronizzazione qui non è evitata, ma solo spostata sulla costellazione dei satelliti: è infatti indispensabile che i satelliti siano sincronizzati tra di loro. Se cosı̀ non fosse, ciascun satellite aggiungerebbe al sistema una equazione e una incognita, mentre cosı̀ c’è una sola T, indipendentemente dal numero di satelliti utilizzati. Active Bat Questo sistema prevede la trasmissione di due impulsi, uno RF (veloce) e uno a ultrasuoni (lento). Il time-of-flight del primo è trascurabile rispetto a quello del secondo, quindi si suppone che il primo sia istantaneo, e viene utilizzato per sincronizzare il trasmettitore e il ricevitore. Dopo questa sincronizzazione si misura il time-of-flight del secondo e lo si usa per calcolare la distanza. 1 Tre sfere si intersecano in due punti, non in uno. Ma solo uno è sulla superficie della terra, l’altro invece è nello spazio; quest’ultimo valore viene facilmente identificato e scartato. Capitolo 2 Perché la sincronizzazione LC: che diavolo sto guardando? quand’è che questo accade nel film? CN: adesso! sta guardando l’adesso signore! tutto ciò che avviene adesso sta avvenendo adesso LC: che è successo al prima? CN: è passato LC: quando? CN: adesso. siamo all’adesso adesso LC: torniamo al prima CN: quando? LC: adesso CN: adesso? LC: adesso CN: non posso LC: perché? CN: l’abbiamo superato LC: quando? CN: proprio adesso! LC: quando il prima sarà adesso? CN: presto! Lord Casco e Col. Nunziatella, “Balle Spaziali” Perché una Wireless Sensor Network deve essere sincronizzata? Prima di analizzare i metodi di sincronizzazione, vogliamo soffermarci sulle motivazioni. In questo capitolo descriveremo vari utilizzi di una scala dei tempi comune in una Wireless Sensor Network. E’ importante far notare che gli utilizzi sono molti e diversi tra di loro, e che questa diversità ci impedirà di usare un singolo metodo di sincronizzazione per tutte le applicazioni. 14 Perché la sincronizzazione 2.1 Integrazione dei dati provenienti da più sensori Una delle motivazioni principali dello sviluppo delle sensor network è la possibilità di tenere sotto controllo fenomeni distribuiti su un’area geografica molto vasta. Infatti il fenomeno da misurare potrebbe non essere rilevabile a distanza, quindi non è efficace l’utilizzo, come di consueto, di pochi sensori che non possono— se il fenomeno è distribuito—essere sempre vicini ai punti che si ha interesse a misurare. Un altro vantaggio delle sensor network è che permettono di ottenre molte più informazioni delle singole misure effettuate da ciascun nodo. Figura 2.1: I sensori forniscono una informazione binaria, o rilevano il fenomeno (e quindi sono all’interno dell’area interessata dal fenomeno stesso) o non lo rilevano (e quindi sono all’esterno). Integrando le informazioni di posizione dei sensori stessi possiamo ricavare anche informazioni sull’estensione del fenomeno e sulla “forma” dell’area da questo interessata, sebbene i nodi in se non abbiano sensori di “estensione” e di “forma”. Vediamo ad esempio la situazione di Figura 2.1: il fenomeno da misurare potrebbe essere una chiazza di petrolio che galleggia sull’acqua, risultato dell’incidente di navigazione di una petroliera. Le singole letture dei sensori ci dicono solamente se nel punto in cui si trova il sensore la concentrazione di petrolio è superiore o inferiore ad una certa soglia, ma se integriamo questi valori con i dati di posizione di tutti i sensori riusciamo a misurare anche la grandezza della chiazza e la sua forma. Le informazioni fornite dall’insieme dei sensori sono quindi maggiori della somma delle informazioni fornite dai singoli sensori: nell’esempio si è riusciti a determinare un’area e una forma anche se i nodi non erano equipaggiati con sensori di “area” e di “forma”. 2.1 Integrazione dei dati provenienti da più sensori 2.1.1 15 Approccio di tipo brute force Nelle integrazioni di dati come quella vista poco fa non c’è necessità di una sincronizzazione temporale, dal momento che la situazione descritta non era tempovariante: la chiazza galleggiante sull’acqua si supponeva ferma e dunque le misure di concentrazione dei vari sensori non cambiavano nel tempo. Consideriamo il caso in cui la chiazza fosse invece in movimento, a prima vista sembra che il sistema di localizzazione appena descritto possa funzionare anche come sistema di rilevazione del movimento semplicemente ripetendo le misurazioni nel tempo. Se le misure arrivano tutte ad un elaboratore centrale, che si occupa di memorizzare l’istante di arrivo con un timestamp ad esso locale, non è necessaria nessuna sincronizzazione esplicita dei nodi. Questo sistema funziona per movimenti molto lenti, ad esempio il tracking del movimento di container in una zona del porto. È sufficiente memorizzare le posizioni degli stessi a intervalli molto larghi, ad esempio ogni volta che vengono spostati, per ricostruire ogni movimento; non è necessario che la trasmissione dell’informazione di posizione al server centrale avvenga con una bassa latenza, dal momento che la velocità di spostamento dell’oggetto non è un fattore rilevante. 2.1.2 Necessità di approcci migliori Nel momento in cui la velocità dell’oggetto da tracciare aumenta, la latenza con cui vengono trasmesse le rilevazioni diventa cruciale: in una applicazione di tracking di un autoveicolo, ad esempio, la velocità di spostamento è molto alta e il più piccolo ritardo di trasmissione tra un sensore e la base station può falsare la misura. La distanza j che può essere percorsa dall’oggetto nel tempo impiegato alla rilevazione dell’oggetto stesso per essere trasmessa alla base station è non trascurabile. La caratteristica della rete di essere distribuita tende ad aumentare j: solitamente i nodi hanno un range di trasmissione molto basso, per minimizzare il consumo energetico (che cresce con la distanza con andamento r2 in campo aperto, con andamento r4 , misurato empiricamente, in caso di una riflessione [27]), e dunque un messaggio che attraversa la rete deve effettuare molti hop, ciascuno dei quali introduce ritardo. Altra fonte di ritardo è il fatto che, sempre per mantenere basso il consumo energetico, i nodi non trasmettono sempre ma attuano una qualche politica di duty-cycling, che alterna periodi di trasmissione a periodi molto più lunghi di inattività: passare dallo sleep mode allo stato attivo richiede tempi nell’ordine di 6µs (su tmote sky). Il bitrate, mantenuto basso per 16 Perché la sincronizzazione evitare di usare potenze di trasmissione elevate, è anch’esso importante, come lo sono le ritrasmissioni dovute alla mancata ricezione dei pacchetti causate da disturbi ambientali. Dal momento che una vasta classe di fenomeni da misurare ha la caratteristica di avere velocità elevate, nel progetto di una sensor network si deve tener conto di questa particolare caratteristica. È necessario effettuare il timestamping degli eventi all’interno della rete, per opera del nodo stesso che ha effettuato la misurazione o comunque molto vicino: abbiamo dunque bisogno di una rete sincronizzata. 2.2 In-Network Processing Abbiamo visto come l’integrazione di più misurazioni effettuate in istanti diversi in differenti punti della rete richieda la sincronizzazione dei sensori, e che sebbene per alcune applicazioni in cui l’elaborazione dei dati viene effettuata a livello centrale sia possibile fare altrimenti, nella maggior parte delle situazioni reali il ruolo della sincronizzazione è molto importante. Un modello che prevede un nodo centrale che si occupa di elaborare i dati sottintende che vi sia una maniera semplice per trasmettere ogni lettura dei dati “grezzi” dal nodo all’elaboratore centrale: ciò non è vero già nei normali sistemi distribuiti, dal momento che è difficile progettare algoritmi che scalino al meglio su molti nodi e che un guasto su un singolo nodo renderebbe il sistema poco stabile, e lo è ancor meno nelle sensor network per via della necessità di limitare il consumo energetico. Dal momento che per aumentare la vita utile dei nodi sono precluse comunicazioni frequenti e a lunga distanza, si cerca di effettuare la quantità maggiore di processing dei dati a livello del singolo nodo e di limitare al massimo la collaborazione con altri nodi. Ad esempio un nodo può effettuare la correlazione di un segnale audio che ha registrato con un pattern desiderato, e segnalare solo le corrispondenze positive evitando di trasmettere tutto ciò che registra al nodo centrale per effettuare lı̀ il processing. Una sorta di collaborazione, sempre nell’ottica dell’efficenza, è scartare misurazioni che sono rilevate da un solo nodo di un gruppo di nodi vicini nello spazio, o di non ritrasmettere informazioni “doppie” dello stesso evento rilevato da nodi vicini. La collaborazione con i nodi vicini e il processing locale dei dati sono la chiave 2.3 Azione Coordinata 17 per ottenere un sistema efficente dal punto di vista energetico; in generale un buon sistema riduce quanti più dati possibile quanto prima possibile per evitare di dover consumare molte risorse per trasmettere i dati grezzi (o quasi) ai livelli superiori dell’applicazione. Un esempio di data reduction è l’eliminazione dei doppioni, come citato prima, nella quale i nodi evitano di segnalare eventi che sono già stati segnalati da nodi vicini: in questo caso una sincronizzazione precisa è indispensabile per distinguere se si tratta proprio dello stesso evento o di due eventi simili che si sono verificati quasi contemporaneamente. Un altro esempio lampante si ha nel tracking di oggetti in movimento, in cui la trasmissione di un vettore velocità da un nodo all’utente è molto più veloce che la trasmissione delle misurazioni di prossimità di vari sensori perché siano poi elaborate centralmente. 2.3 Azione Coordinata Finora abbiamo descritto le reti di sensori come una struttura passiva capace solo di rilevazioni e misurazioni nell’ambiente ma non di agire nell’ambiente stesso. Esistono invece vari esempi di reti che possono effettuare una qualche azione sull’ambiente stesso: anche in questo caso la presenza di sincronizzazione è fondamentale. Pensiamo a nodi che possono muoversi nell’ambiente: la distribuzione degli stessi potrebbe essere modificata per supplire a spegnimenti di nodi (e quindi a “buchi” nella rete) oppure per migliorare la precisione delle misurazioni, ad esempio per determinare i confini di un fenomeno (riprendiamo l’esempio della chiazza di petrolio in Figura 2.2). Esistono altre forme di attuazione oltre allo spostamento di nodi: i sensori possono emettere suoni, rilasciare sostanze chimiche, applicare pressioni, o semplicemente spegnersi o accendersi. Anche il sistema di Radio Scheduling efficente che descriviamo nel paragrafo 2.4 può essere considerata una azione coordinata. Più in generale, si considera che la sincronizzazione è necessaria anche per coordinare azioni compiute dai nodi sull’ambiente, si pensi a macchine a controllo numerico in una fabbrica che devono agire in maniera coordinata, tutte allo stesso istante oppure secondo una sequenza temporizzata ben precisa. 18 Perché la sincronizzazione Figura 2.2: sinistra) una rete di sensori determina la forma di una chiazza di petrolio che galleggia sull’acqua, disegnando un poligono attorno ai sensori che appartengono alla zona interessata dal fenomeno destra) se i sensori sono mobili, possono modificare la loro posizione per determinare l’estensione della chiazza con maggiore accuratezza. 2.4 Radio Scheduling efficente Le radio a basso consumo e a corto raggio usate nei nodi di sensor network consumano praticamente la stessa quantità di energia sia che stiano trasmettendo sia che stiano ascoltando passivamente il canale. Il protocollo MAC è quindi progettato per minimizzare questo tempo di attesa, spegnendo la radio per il maggior tempo possibile, e accendendola solo per brevi periodi in cui vengono scambiati messaggi; l’idea di partenza di questi protocolli è il TDMA. Il risparmio di energia è direttamente correlato alla precisione della sincronizzazione. Consideriamo due nodi wireless che devono “incontrarsi” sul canale radio una volta ogni 60 secondi, l’uno per tasmettere e l’altro per ricevere uu breve messaggio di 8 bit contenente una misurazione. Usando una radio a 19,2kbit/sec, 8 bit sono trasmessi in circa 0,5 millisecondi, ma in pratica le radio dovranno accendersi un certo periodo di tempo prima (guard time) per compensare l’errore con cui il nodo remoto ha misurato l’intervallo di tempo tra un rendezvous e il successivo, come si vede in Figura 2.4. Un errore di fase di solo 1ms triplica l’energia consumata dalla radio per ascol- 2.5 Localizzazione per mezzo di segnali acustici 19 Figura 2.3: Nello scheduling TDMA i nodi devono svegliarsi un po’ prima dallo sleep a causa dell’errore di sincronizzazione. Una sincronizzazione precisa permette di ridurre questo guard time, quindi ridurre il tempo che un nodo passa ad ascoltare il canale, operazione che in una sensor network è onerosa—in termini di energia consumata—quanto la trasmissione. tare il canale (perchè la radio rimane accesa per 1,5ms invece che per i 0,5 ms necessari per trasmettere il messaggio), e il fenomeno si fa maggiormente sentire più aumenta la velocità di trasmissione. In più, anche se si suppone la perfetta sincronizzazione all’inizio del periodo di sleep, si deve fare i conti con il drift tipico dell’oscillatore al quarzo, che sappiamo essere dell’ordine di 1 parte su 105 [35], cioè 0,6ms dopo 60 secondi. Ovviamente la spedizione di pacchetti di sincronizzazione durante il periodo di sleep rende inutile il periodo di sleep stesso, quindi prevedere — nel progettare un algoritmo di sincronizzazione — meccanismi di stima e correzione del drift della frequenza. L’esempio dimostra non solo l’importanza della sincronizzazione, ma anche la difficoltà nell’effettuarla, in quanto essa sottrae risorse alle normali operazioni svolte dalla rete di sensori. Una buona sincronizzazione riduce il guard time, e nel fare questo è aiutata dall’applicazione: maggiore è il numero di pacchetti ricevuti, maggiore la possibilità di ricevere informazioni di sincronizzazione inserite nei pacchetti stessi con la tecnica del piggybacking. 2.5 Localizzazione per mezzo di segnali acustici La localizzazione nello spazio è una necessità di molte applicazioni viste in questo capitolo, che richiedono sia nota la “posizione” nel tempo e nello spazio dei nodi. Nei casi più semplici si possono misurare manualmente le posizioni dei singoli nodi e inserirle “hard coded” nell’applicazione stessa: questo metodo però è complesso 20 Perché la sincronizzazione da gestire, non scala all’aumentare delle dimensioni della rete, dev’essere ripetuto ogni volta che si mette in funzione una nuova rete e non riesce a gestire la mobilità di nodi. Vi è dunque bisogno di un sistema automatico che permetta la localizzazione dei nodi. Un metodo comunemente usato è basato sulla localizzazione per mezzo di segnali acustici (acoustic ranging), nella quale un nodo emette un suono che può venire udito in una certa area. Se i nodi sono sincronizzati, possono calcolare il tempo tra l’emissione del suono e la sua ricezione, e conoscendo la velocità del suono nell’aria possono risalire alla distanza percorsa. Anche in questo come in altri metodi, viene usata la triangolazione di più misurazioni per determinare la posizione, e la ripetizione delle stesse misure per migliorare la statistica dell’errore. 2.6 Array Processing Per array processing si intende l’analisi e l’elaborazione di dati provenienti da più sorgenti. Quando si tratta di sorgenti eterogenee (tipologie diverse di sensori) si parla di data fusion. Ci sono varie applicazioni nell’ambito del signal processing, quali riduzione del rumore, localizzazione della sorgente del rumore, controllo dei processi, codifica di sorgente, che è interessante implementare su un sistema distribuito. D’altra parte, finora questi algoritmi sono stati implementati su una singola macchina, usando quindi una sincronizzazione implicita (ovvero tutte le misurazioni condividevano comunque una scala temporale comune). Un esempio classico, ancora una volta, è la localizzazione della sorgente di un rumore (beamforming), che si basa sull’assunto che le differenze di fase tra gli orologi di ricevitore e trasmettitore sono dovute solo al time-of-flight del segnale, e quindi possono essere convertite in distanze con un rapido calcolo. Notiamo che lo stesso “trucco” usato nel GPS, di fare più misurazioni di quelle necessarie per aggiungere equazioni al sistema, è qui usato quando la sorgente del segnale non è sincronizzabile con la rete di sensori, ad esempio se si tratta di un animale selvatico, che ovviamente non è in possesso di un trasmettitore radio con un orologio sincronizzato. L’istante in cui il rumore è stato generato è un’altra incognita del sistema, e per risolverlo si aggiungono altre equazioni, cioè misurazioni del tempo di ricezione del rumore da parte di altri nodi. 2.7 Usi in sistemi distribuiti tradizionali 2.7 21 Usi in sistemi distribuiti tradizionali Gli usi descritti finora sono perlopiù propri delle sensor network. Le reti di sensori sono comunque anche dei normali sistemi distribuiti, nei quali la sincronizzazione è usata in maniera massiccia. Ecco alcuni esempi: • Logging e Debugging: durante il debug di una applicazione, si devono spesso confrontare i log di vari nodi a certi istanti particolari per ricostruire il funzionamento del sistema. Log non sincronizzati rendono impossibile il determinare le relazioni di causalità tra eventi nel sistema o anche solo ricostruire l’esatta sequenza degli eventi stessi. • Consistenza e Stato della rete: molti algoritmi si basano su meccanismi di consenso distribuito per determinare alcuni parametri funzionali. La sincronizzazione serve a distinguere le informazioni di consistenza o di stato emesse più di recente e che sono dunque considerate più valide di quelle emesse meno recentemente. • Query a database: il progetto TinyDB ha applicato la semantica dei database alle reti di sensori, permettendo di ricavare parametri funzionali o di misurazioni dalla rete tramite query di tipo SQL. Questi sistemi si propongono di nascondere all’utente il fatto che vengono effettuate delle query distribuite sulla rete invece che su un database centralizzato. Affinchè le query abbiano lo stesso significato su tutta la rete (ad esempio, “dammi le letture degli ultimi cinque minuti”) è necessario tutti i nodi siano sincronizzati. • Interazione con l’utente: gli utenti utilizzano standard di tempo assoluti, come UTC, per effettuare le loro interrogazioni (ad esempio: “dammi le letture tra le 12 le 13 di sabato 18 marzo”). Perché queste interrogazioni siano interpretate in maniera corretta è necessario che almeno un nodo sia sincronizzato con una sorgente di tempo UTC, e che tutti i nodi della rete siano a loro volta sincronizzati esso. • Crittografia: dal momento che molte applicazioni affidate a sensor network sono critiche, è interessante usare schemi crittografici per impedire attacchi o intromissioni di persone non autorizzate nella rete. Solitamente gli schemi di autenticazione si basano su un riferimento temporale per garantire che le informazioni scambiate siano recenti, al fine di evitare attacchi a ripetizione, riutilizzo di vecchi messaggi di autenticazione o altre forme di attacco. 22 Perché la sincronizzazione Esistono inoltre delle tecniche per falsare la sincronizzazione tra nodi al fine di disturbare le trasmissioni sulla rete o falsare i risultati di un algoritmo di localizzazione, come si vede in [31]. 2.8 Conclusioni Abbiamo visto che la sincronizzazione è un servizio essenziale che deve essere presente nelle reti di sensori. Molte applicazioni si basano su di essa, praticamente tutte quelle che elaborano in qualche modo dati provenienti da sensori diversi e raccolti in istanti temporali diversi. Dalla localizzazione spaziale, all’aggregazione dei dati, al tracking, al radio scheduling efficente, ad applicazioni “tradizionali” di sistemi distribuiti, come debug e analisi del sistema, interazione con gli utenti, osservazioni dello stato del sistema e crittografia. È dunque chiaro che una qualche forma di sincronizzazione deve esserci in una sensor network. La grande varietà delle applicazioni però ci fa capire che non sarà facile trovare una soluzione che vada bene per tutti; nel prossimo capitolo cercheremo dunque di definire delle metriche che ci permettano di specificare quali sono i requisiti—riguardo alla sincronizzazione—di cui abbiamo bisogno per la nostra sensor network. Capitolo 3 Caratteristiche del clock Millesimo di secondo: tempo trascorso tra il passaggio del semaforo al verde e il primo colpo di clacson. Nel capitolo precedente abbiamo descritto varie applicazioni di una sensor network, ciascuna delle quali ha diverse esigenze in merito alla sincronizzazione. Le implementazioni della rete stessa possono variare in maniera significativa: le Wireless Sensor Network sono molto orientate all’applicazione, e quindi ciascuna rete può differenziarsi dalle altre nel software, nell’hardware disponibile, nelle limitazioni d’uso dello stesso, nell’estensione e nella durata operativa richiesta. In una tale situazione è impossibile definire con precisione e in generale le richieste che deve soddisfare il servizio di sincronizzazione di una sensor network. Tuttavia, avere varie metriche che caratterizzano aspetti differenti della sincronizzazione può essere utile, sia per rendersi conto in fase di progetto di che cosa ha bisogno un’applicazione, sia per definire i limiti di utilizzo di un particolare metodo di sincronizzazione. In questo capitolo esamineremo tali metriche, dopo aver presentato brevemente il concetto di clock e alcuni semplici modelli per i casi più diffusi. 3.1 Modello del clock I clock digitali sono misuratori di intervalli temporali. Tipicamente consistono di un contatore h (che d’ora in poi chiameremo clock “locale”) che conta intervalli temporali, idealmente tutti della stessa lunghezza; indicheremo il valore di questo contatore all’istante t come h(t). Il contatore è incrementato da un oscillatore ad una frequenza f . La frequenza f al tempo t è data dalla derivata prima di h(t), 24 Caratteristiche del clock cioè f (t) = dh(t)/dt. In un clock ideale la lunghezza degli intervalli temporali dovrebbe essere sempre uguale, ma nei clock reali questa dipende da variazioni nella tensione di alimentazione, nella temperatura, ecc. Se queste variazioni fossero completamente casuali, ovviamente l’informazione fornita dalla lettura del clock non sarebbe di alcun significato. Fortunatamente, tali variazioni sono contenute entro limiti noti. A seconda di come vengono modellizzate queste variazioni, possiamo distinguere tre tipi di modelli del clock: Constant-rate Si assume che la frequenza con cui viene incrementato il contatore sia costante, cioè f (t) = fcost = 1. Questo approccio è valido se la precisione richiesta è piccola rispetto alla fluttuazione della frequenza. Bounded-skew La variazione dal valore atteso della frequenza con cui viene incrementato il contatore si assume limitata. Chiamiamo questa variazione skew, cioè ρ(t) = f (t) − 1 = dh(t)/dt − 1, e i limiti entro cui questo varia ρmax : −ρmax ≤ ρ(t) ≤ ρmax ∀t (3.1) Un’altra ipotesi ragionevole è che sia ρ(t) > −1 per ogni t. Questo significa che un clock non può mai fermarsi (ρi (t) = −1) o decrescere (ρi (t) < −1). Quindi, se due eventi a, b con ta < tb sono rilevati dal nodo Ni , il cui skew ρi è limitato secondo (3.1), allora il nodo Ni può calcolare i limiti inferiore e superiore ∆li [a, b] e ∆ui [a, b] alla differenza dei due tempi ∆[a, b] := tb − ta come: ∆li [a, b] := hi (tb ) − hi (ta ) 1 + ρmax ∆ui [a, b] := hi (tb ) − hi (ta ) 1 − ρmax (3.2) Questo modello è comunemente usato dal momento che i limiti sopracitati sono spesso forniti dal produttore degli oscillatori. I nodi di una sensor network usano oscillatori poco costosi con ρmax ∈ [10ppm, 100ppm] 1 . E’ importante far notare che in questo modello lo skew può oscillare liberamente entro i limiti specificati in (3.1). Il prossimo modello darà un limite alla variazione dello skew. Bounded-drift La derivata prima della variazione dal valore atteso della frequenza con cui viene incrementato il contatore, che chiamiamo emphdrift, si assume limitata. In altri termini, la variazione ϑmax = dρ(t)/dt si assume limitata −ϑmax ≤ ϑ(t) ≤ ϑmax 1 ∀t (3.3) Parti per milione, cioè 10−6 . Un oscillatore con un drift di 100ppm ha una deriva di 100 secondi in un milione di secondi, o 100µs in un secondo. 3.2 Metriche 25 L’uso di questo modello è accettabile se la variazione della frequenza (il drift) è dovuta solo a cause che variano gradualmente nel tempo come temperatura o voltaggio della batteria. In questo caso è possibile compensare in maniera accettabile per il drift, calcolando una sua stima all’istante corrente e prevedendo i valori dello stesso nel futuro più prossimo. 3.1.1 Software clock Un algoritmo di sincronizzazione può modificare direttamente il valore del clock locale oppure mantenere un clock software, cioè una funzione che prende in input il clock locale h(t) e lo trasforma in una funzione tempo c(h(t)), che è poi il prodotto finale della sincronizzazione. Ad esempio c(h(t)) = t0 + A · [h(t) − h(t0 )] è una funzione tempo che parte dall’istante t0 , e inizia a contare con h(t) − h(t0 ) con la stessa frequenza del clock locale h (A mette in relazione l’unità di misura dei valori del software clock con quella del tempo c(·)). In generale la funzione c(h(t)) che costituisce un clock software è continua e strettamente monotona crescente. 3.2 3.2.1 Metriche Errore di Fase L’errore di fase è in assoluto la metrica più utilizzata per analizzare le prestazioni di algoritmi di sincronizzazione. È definito come la differenza tra i valori di due clock in un dato istante t. Ci sono vari modi di considerare questo errore: l’errore di coppia (pairwise error) è la differenza tra i tempi segnati dai clock di due nodi. La dispersione di gruppo (group dispersion) è il più alto tra gli n2 errori tra ciascuna coppia in un gruppo di nodi. L’errore può anche essere considerato rispetto al tempo segnato da un riferimento esterno (vd. 3.2.6). Le applicazioni che girano su una sensor network sono molto spesso sensibili al valore massimo dell’errore e non alla sua media. Per questo motivo, le prestazioni di un algoritmo di sincronizzazione sono valutate anche indicando l’errore più alto su un determinato numero di prove o una sua percentuale (ad esempio il valore peggiore dell’errore sul 95% delle prove). Il massimo valore tollerabile per l’errore dipende comunque dall’applicazione e dalla frequenza con cui si verifica il fenomeno che i sensori stanno rilevando. Ad esempio, in una applicazione di motion tracking l’errore ammissibile è collegato 26 Caratteristiche del clock alla velocità con cui si muove il soggetto in movimento all’interno della zona che il sensore sta monitorando, e dalla precisione richiesta nella localizzazione. Tra le recenti applicazioni note per sensor network quella che richiede i limiti più stretti per l’errore di sincronizzazione è la localizzazione della sorgente di impulsi sonori (acoustic ranging): i codec audio campionano il segnale tipicamente a 48Khz, quindi un campione ogni 20,8 µsec. A temperatura controllata, il suono in questo intervallo di tempo percorre 7,1mm, quindi per ottenere una precisione inferiore al centimetro è necessario che l’errore di fase sia abbastanza basso da permettere di distinguere singoli campioni, quindi circa 10µsec. Un’altra applicazione, nel campo sismologico, è la rilevazione della propagazione di fronti d’onda sismici: questi si propagano circa dieci volte più velocemente del suono, ma in queste applicazioni la richiesta di precisione spaziale è minore, quindi un errore di fase nell’ordine del millisecondo (che porta ad un errore spaziale di circa 3m) è accettabile. 3.2.2 Errore di Frequenza L’errore di fase è una metrica istantanea: ci permette di stabilire, in un dato momento, “quanto distanti sono” due clock. L’errore di frequenza, invece, stabilendo le differenze delle frequenze degli oscillatori, ci permette di stimare l’errore di fase col passare del tempo: se due clock sono sincronizzati adesso, conoscendo con che velocità avviene la deriva dei clock possiamo sapere quanto saranno sincronizzati, ad esempio, tra 60 secondi. Come abbiamo visto nel paragrafo 1.3, tutti i clock hanno una frequenza “nominale” ed una “reale”. Alcuni metodi di sincronizzazione non si curano della differenza tra la frequenza “nominale” e la frequenza effettiva del clock, e semplicemente aggiornano il valore del clock ogni volta che è trascorso un intervallo di tempo τ , come si vede in Figura 3.1; un esempio comune è utilizzare un ricevitore GPS che genera un impulso periodico, e ad ogni periodo il clock viene sovrascritto con il nuovo valore fornito dal GPS. Un altro metodo, migliore, è stimare la differenza tra la frequenza nominale dell’oscillatore e quella reale, cosı̀ da poter applicare una serie di piccole correzioni più frequentemente, ad esempio ad ogni tick del clock, quindi nell’ordine dei millisecondi o meno). NTP, ad esempio, può sincronizzare un clock basandosi sul segnale periodico proveniente da un ricevitore GPS o da un altro pc in rete su cui gira NTP. In genere, gli algoritmi che stimano la frequenza hanno performances migliori 3.2 Metriche 27 Figura 3.1: Un clock che funziona ad una frequenza diversa dalla sua frequenza nominale. Alcuni algoritmi semplicemente allineano la fase dopo un intervallo di tempo più o meno lungo. Altri, come NTP, stimano al differenza tra la frequenza nominale e quella desiderata cosicchè τ possa essere mantenuto piccolo. Questo riduce le discontinuità nella scala temporale (le ‘seghettature’ in Figura, e permette al clock di degradare senza brusche variazioni anche se viene a mancare la sincronizzazione con il riferimento di frequenza. di quelli che non lo fanno. Mantenere τ piccolo fa si che non si vedano grosse discontinuità della scala temporale (grosse variazioni in un piccolo intervallo di tempo). Inoltre, se viene a mancare per un certo tempo il riferimento di frequenza, è verificato sperimentalmente che gli algoritmi che stimano la frequenza hanno un errore di fase minore di quelli che lavorano solo con la correzione di fase, e questo è particolarmente importante in una Wireless Sensor Network, dove la connettività è intermittente. 3.2.3 Validità temporale (lifetime) La validità temporale della sincronizzazione è l’intervallo di tempo in cui possiamo ritenere i clock sincronizzati. Vi sono vari tipi di validità temporale nelle sensor network, da poco meno di un secondo a tempi molto più lunghi. Per chiarire il concetto, richiamiamo l’applicazione di localizzazione citata nel par. 2.5: i nodi localizzano la posizione del soggetto misurando i tempi di arrivo dell’onda sonora da esso prodotta. In questo caso ai sensori basta essere sincronizzati momentaneamente, cioè negli istanti impiegati dal suono per giungere a tutti i 28 Caratteristiche del clock sensori. Consideriamo invece che debba essere fatto il tracking dei movimenti del soggetto per un tempo più lungo, magari mentre si muove nell’ambiente: in questo caso i nodi devono essere sincronizzati per un tempo più lungo. Fortunatamente, il fatto che il soggetto si muova ad una velocità molto più lenta di quella dei rumori che produce fa si che l’errore di fase tollerabile in questo tipo di applicazioni sia molto alto. Altre applicazioni come controllo distribuito e scheduling di eventi/processi richiedono una sincronizzazione valida per un tempo molto lungo, pari anche al tempo di operatività della rete. Infine esistono applicazioni di data logging che spesso richiedono una sincronizzazione UTC - lo standard internazionale per la misura del tempo - perché è persistente, e valido indipendentemente dalla particolare rete di sensori che si sta utilizzando. 3.2.4 Validità spaziale (scope) Per validità spaziale si intende l’area in cui è definita una scala temporale: i nodi distribuiti su quest’area saranno dunque sincronizzati sullo stesso tempo. Molto spesso il concetto di area è geografico, ma può essere comodo considerare altri tipi di distanze che si rifanno alla topologia della rete, come ad esempio il numero di hop che separano un nodo da un altro. Solitamente in una sensor network queste due distanze sono correlate perché la comunicazione avviene via radio, e la distanza entro la quale un nodo può trasmettere è limitata. Molti algoritmi sincronizzano i nodi che sono raggiungibili con una trasmissione broadcast, ma in generale è necessario sincronizzare anche i nodi raggiungibili attraverso un percorso di più hop. Solitamente, i nodi “periferici”, cioè quelli che distano un maggior numero di hop dal nodo che da il riferimento temporale, hanno un errore di fase maggiore dato dall’accumulazione degli errori di fase in ciascun hop. Il GPS fa eccezione in quanto fornisce sincronizzazione che ha come validità spaziale l’intero pianeta, con lo stesso errore di fase indipendentemente dalla posizione. Anche se man mano che cresce la dimensione della rete crescono di conseguenza gli errori di sincronizzazione, questo è accettabile in quanto, nel mondo reale, i fenomeni distribuiti su una vasta area hanno dei tempi caratteristici più lunghi, quindi errori di sincronizzazione più alti solitamente sono tollerabili. 3.2 Metriche 3.2.5 29 Disponibilità Per disponibilità si intende la possibilità per un nodo di accedere alla sincronizzazione. La non completa disponibilità si ha quando un nodo non ha o non può usare (temporaneamente o meno) le risorse necessarie per accedere alla sincronizzazione, ad esempio un nodo può fornire la sincronizzazione ad una rete tramite trasmissione broadcast del suo tempo locale, ma uno degli altri nodi della rete può per un qualche motivo (propagazione radio, mancanza di energia, ...) non ricevere questi pacchetti, per cui per questo la sincronizzazione non è disponibile. Nel caso del GPS ad esempio, la disponibilità è limitata ai nodi equipaggiati di un ricevitore GPS, e in linea di visibilità con almeno quattro satelliti (il GPS non funziona all’interno di edifici, sotto alberi con le foglie umide o sott’acqua). 3.2.6 Interno/Esterno In molti sistemi distribuiti, il fatto che la rete sia sincronizzata significa che “tutti i nodi segnano il tempo correttamente”. Questo implica che esista una nozione di tempo “corretto”, che solitamente è l’UTC. Nelle reti di sensori, molto spesso però non è necessario che il tempo sia assoluto, basta che via sia una qualche scala temporale condivisa dai nodi della rete, per i seguenti motivi: • ordinamento di eventi—molte applicazioni hanno bisogno di registrare sequenze di eventi nell’ordine in cui essi si sono verificati, ma non hanno necessariamente bisogno di una scala dei tempi assoluta. In questi casi non è dunque importante la frequenza dei clock, ma semplicemente gli offset. Lamport porta questa idea agli estremi (vd. 1.6) non utilizzando del tutto un clock fisico, ma un “clock virtuale” che scatta di un “tick” ogni volta che si verifica un evento. • controllo coordinato—molte applicazioni distribuite eseguono delle operazioni in maniera coordinata; in molti casi non è importante il momento esatto in cui queste vengono eseguite ma il fatto che vengano eseguite nello stesso momento da tutti i nodi. Ad esempio, lo scheduling TDMA nella trasmissione radio e il coordinamento di stormi di robot mobili. Si dice che questi tipi di applicazioni necessitano di una sincronizzazione interna o relativa, ovvero la rete dev’essere internamente consistente, ma non interessa relazionare la scala dei tempi interna alla rete con un riferimento esterno/assoluto. 30 Caratteristiche del clock Una seconda classe di applicazioni è quella che richiede sincronizzazione ester- na, ovvero che la scala temporale sia espressa nei termini di un riferimento assoluto, ad esempio UTC. Questo è necessario ad esempio nell’interazione con gli utenti, i quali molto spesso si esprimono in termini di tempo assoluto; per rispondere alla richiesta “Mostrami tutti gli eventi che si sono verificati tra le 9 e le 11”, il richiedente e la rete devono condividere il riferimento temporale usato. Questa sincronizzazione è necessaria anche nelle applicazioni che archiviano dati, in quanto la scala temporale deve rimanere consistente anche quando la rete dei nodi che ha rilevato tali misure non sarà più operativa. Infine c’è una terza classe di applicazione, che potremo chiamare ibride. In molti casi infatti i nodi hanno bisogno di condividere la frequenza di aggiornamento del clock ma non il tempo: non importa cioè quale particolare secondo ciascun nodo sta contando, quanto il fatto che tutti i “secondi” dei vari nodi abbiano la stessa durata. In queste applicazioni la scala temporale interna alla rete viene convertita in un qualche modo in un riferimento assoluto per permettere l’analisi e la correlazione dei dati, molto spesso tramite uno dei nodi della rete che, oltre ad essere sincronizzato internamente, lo è anche con un riferimento temporale esterno. 3.2.7 Consumo energetico Una delle caratteristiche a cui prestare maggiormente attenzione nel progetto di una sensor network è il consumo energetico, nonostante sia difficile quantificarlo in anticipo per la varietà di hardware e di situazioni operative in cui la rete si può trovare. Ci sono nodi con ampia disponibilità di batterie, che possono quindi rimanere sempre accesi, mentre altri che hanno una riserva energetica che permette appena di svegliarsi dallo sleep mode, effettuare una misurazione, spedirla via radio e tornare in sleep. I metodi di sincronizzazione sono diversi: alcuni richiedono la trasmissione di un solo messaggio in broadcast, altri richiedono invece molti messaggi da entrambe le parti in causa e consumano quindi più energia. Alcuni nodi hanno bisogno di hardware particolare, ad esempio ricevitori GPS od oscillatori molto precisi, che consumano molta corrente. Dal momento che la trasmissione via radio è sicuramente la causa maggiore del consumo energetico dei nodi di una sensor network, una metrica sul consumo dell’energia deve tener conto principalmente del numero di messaggi trasmessi e ricevuti, quindi del tempo per cui il chip radio rimane acceso. Anche l’utilizzo 3.2 Metriche 31 della CPU per lunghi periodi influisce negativamente sul consumo energetico e dunque sulla durata della batteria. 3.2.8 Tempo di convergenza Gli algoritmi di sincronizzazione non danno subito una risposta: dal momento in cui vengono avviati nella rete, possono passare da alcuni millisecondi a molti minuti perché la rete stessa sia sincronizzata. In caso di nodi che non hanno problemi di consumo energetico, la rete può essere mantenuta sempre sincronizzata, anche se ciò richiede continui scambi di messaggi di sincronizzazione, e anche se l’informazione temporale non viene sempre utilizzata. In questo modo dopo un tempo di startup — anche molto lungo — l’informazione temporale è ottenibile istantaneamente. Dal momento che nella realtà si devono fare i conti con limitazioni di batteria, e i nodi devono quindi stare spenti per lungo tempo, la velocità con cui l’algoritmo converge, cioè da una informazione temporale significativa, è molto importante. D’altra parte gli algoritmi che girano per lungo tempo collezionano una quantità di dati molto maggiore, e realizzano quindi stime più accurate dell’errore di deriva dei clock, cosa che porta a errori di sincronizzazione molto minori. Anche in questo caso, è fondamentale trovare il trade-off migliore in relazione alle richieste della nostra applicazione e alle limitazioni imposte dall’hardware e dalle caratteristiche operative della rete. 3.2.9 Costo e dimensioni Nel caso di metodi di sincronizzazione che usino hardware speciale, è importante considerare il costo di tale hardware e la sua dimensione. In reti che consistono di migliaia di nodi non è possibile equipaggiare ciascun nodo con un ricevitore GPS, in quanto il costo dell’intera rete diventerebbe proibitivo. La dimensione dell’hardware pone un problema simile, è difficile integrare dispositivi grandi (manteniamo il ricevitore GPS come esempio) in nodi molti piccoli, come quelli delle dimensioni di una moneta o meno. 3.2.10 Conclusioni In questo capitolo abbiamo analizzato il problema della sincronizzazione sotto diversi aspetti: questi sono interdipendenti, ed è impossibile ottimizzarne uno 32 Caratteristiche del clock senza influenzare gli altri. Ad esempio: • Non è possibile correggere l’errore di fase senza introdurne uno in frequenza • In grandi reti multi-hop, una sincronizzazione globale porta ad errori di fase più grandi tra i nodi più distanti. • Nelle sincronizzazioni che vengono fatte “una tantum” l’errore di fase cresce nel tempo proporzionalmente all’errore di frequenza. • I risultati migliori nell’errore di fase e frequenza si ottengono con algoritmi che hanno tempo di convergenza lungo; lo svantaggio è dato dall’elevato consumo energetico nel far girare l’algoritmo per lungo tempo. • I metodi che offrono le migliori prestazioni in termini di errore, persistenza e disponibilità richiedono hardware aggiuntivo che è troppo costoso o occupa troppo spazio per essere inserito nei nodi di una sensor network. Ogni algoritmo di sincronizzazione dovrà dunque cercare un compromesso per far si che gli errori cancellati da una parte non vengano re-introdotti da un’altra, mantenere cioè sotto controllo queste metriche e soddisfarle, per quanto possibile, tutte. Capitolo 4 Alle basi della sincronizzazione Il mondo è come te lo fai. Se non ti va, te lo aggiusti. da “Silverado” Nel capitolo che segue introdurremo i meccanismi che stanno alla base della sincronizzazione di due clock: ottenere una lettura di un clock remoto, mantenere la sincronizzazione, combinare varie stime e misure per migliorare la precisione, e organizzare reti composte da un gran numero di nodi. Inoltre analizzeremo nel dettaglio tutta la fase di trasmissione e ricezione di un pacchetto tra due nodi di una Wireless Sensor Network, soffermandoci in particolar modo su tutte le fasi che possono essere fonte di ritardo, deterministico e non. In quest’ultimo caso tenteremo di scrivere un modello probabilistico per l’errore introdotto. Verranno messe in evidenza anche alcune tecniche, poi implementate in vari algoritmi di sincronizzazione, per eliminare alcuni di questi errori. 4.1 4.1.1 Le tecniche Stimare le differenze dei clock Assumiamo di trovarci nella situazione di Figura 4.1(a), con due nodi Ni e Nj che si scambiano messaggi. Sincronizzare questi due nodi significa che i nodi stessi possono mettere in qualche modo in relazione i loro due clock locali hi e hj . 1 1 Indico il valore del clock locale del nodo Ni all’istante ta come hi (ta ) e, con abuso di notazione, lo scrivo nella forma semplificata hia . 34 Unidirezionale: Alle basi della sincronizzazione La soluzione più semplice è illustrata in Figura 4.1(b): il nodo Ni spedisce un pacchetto contenente un timestamp del suo clock locale all’istante a, hia , al nodo Nj , che lo riceve all’istante b (corrispondente al timestamp hjb ). Il nodo Nj non può determinare il tempo di viaggio d del messaggio, sa solamente che il clock locale di Ni valeva hia prima che il suo clock locale valesse hjb . Quindi il suo clock locale quando il messaggio è stato trasmesso sarà stato hja < hjb , e il valore del clock del nodo Ni quando il messaggio è stato ricevuto sarà stato hib > hia . Sincronizzare significa determinare questi hib o hja . Se è noto a priori un limite per il tempo d, cioè dmin < d < dmax , allora hja ≈ hjb − 1/2(dmin + dmax ) (oppure equivalentemente hib ≈ hia − 1/2(dmin + dmax )) minimizza l’errore di sincronizzazione nel caso peggiore. Altrimenti, hjb − dmax e hjb − dmin sono limite inferiore e superiore di hja (e hia + dmin e hia + dmax lo sono per hib ). Figura 4.1: Sincronizzazione unidirezionale e bidirezionale: a) Il nodo Nj determina l’offset del suo clock locale rispetto a un altro nodo Ni , b) usando comunicazioni monodirezionali, o c) e d) usando comunicazioni bidirezionali. A differenza di c), d) permette a entrambi i nodi di misurare il round-trip time. Round-trip: Una soluzione più complessa è illustrata in Figura 4.1(c). Il nodo Nj manda un messaggio al nodo Ni , chiedendo il suo timestamp hib , e misura il tempo di andata e ritorno (round-trip time D = hjc − hja , ovvero la lunghezza dell’intervallo di tempo tra la spedizione della richiesta e la ricezione della risposta. Senza avere nessuna conoscenza precedente sulla natura di d, il nodo Nj sa che 0 < d < D. Se invece ha dei limiti superiore ed inferiore su d, allora il nodo Nj sa che max(D − dmax , dmin ) < d < min(dmax , D − dmin ). Il valore hjb ≈ hjc − D/2 minimizza l’errore di sincronizzazione nel caso peggiore; 4.1 Le tecniche 35 hjc − (D − dmin ) e hjc − dmin sono limiti inferiore e superiore per hjb . Allo stesso modo posso essere determinati dei limiti per hic . Il vantaggio di questo metodo è che fornisce un limite superiore all’errore di sincronizzazione. In [11] si usa questo metodo per rendere l’errore di sincronizzazione minore di un certo valore desiderato: dopo aver ricevuto il messaggio di risposta, il nodo Nj verifica se D/2 − dmin è sotto una determinata soglia. Se non lo è, manda un nuovo messaggio di richiesta e attende una nuova risposta, finchè la coppia richiesta-risposta non soddisfa i requisiti imposti in merito all’errore di sincronizzazione (sotto la soglia). Ovviamente più bassa è la soglia impostata, maggiore sarà — in media — il numero di messaggi trasmessi. Lo svantaggio più evidente di questo tipo di sincronizzazione è che il numero di messaggi trasmessi cresce linearmente con il numero di nodi che comunicano con Ni , mentre nel caso unidirezionale un singolo messaggio broadcast serve un numero arbitrario di nodi. Una combinazione di entrambi gli approcci, nota come eavesdropping synchronization, funziona nel modo seguente: il nodo Nj spedisce un messaggio broadcast che viene ricevuto dal nodo Ni e da un altro nodo Nk , Ni risponde con un altro broadcast che viene ricevuto da Nj e Nk . Il nodo Nk suppone che il secondo messaggio che riceve è stato creato dopo che ha ricevuto il primo, quindi puà calcolare il tempo di round-trip con i timestamp di ricezione dei due messaggi e quello di spedizione da Ni , senza spedire nessun messaggio ma solo ricevendoli. In Figura 4.1(d) vediamo due modifiche del protocollo appena descritto. La prima, non è necessario che Ni risponda subito al messaggio arrivato da Nj , a patto che registri il tempo trascorso tra la ricezione del messaggio e la spedizione della risposta, e inserisca questa informazione nel messaggio di risposta a Nj in modo che quest’ultimo ne possa tenere conto. La seconda, aggiungendo un ulteriore messaggio da Nj a Ni anche quest’ultimo può stimare il tempo di round-trip: il protocollo diventa dunque simmetrico. Reference Broadcasting: In questo approccio è coinvolto un terzo nodo Nk , oltre a Ni e Nj , chiamato beacon node. Il beacon manda un messaggio broadcast, che si suppone dunque arrivare allo stesso istante agli altri due nodi: Ni manda dunque un messaggio — contenente il timestamp hia di arrivo del primo messaggio — al nodo Nj , il quale calcola l’intervallo D = hjb − hja tra il tempo di arrivo dei due messaggi (da Nk e da Ni ) e quindi riesce a calcolare hib ≈ hia + D. 36 Alle basi della sincronizzazione Figura 4.2: Sincronizzazione Reference Broadcast: Un nodo Ni determina l’offset del suo clock locale rispetto a un altro nodo Nj con l’aiuto di un terzo nodo Nk . In c) è illustrata una variante del metodo, da usare se Ni e Nj non possono comunicare direttamente. Il vantaggio di questo metodo è che i messaggi di tipo broadcast sono ricevuti quasi contemporaneamente da tutti i nodi nel range di trasmissione, quindi tipicamente l’errore di sincronizzazione è più piccolo che nei due casi esposti prima; uno svantaggio è la necessità di un terzo nodo che funga da beacon node. Questa tecnica può essere usata anche nella variante illustrata in Figura 4.2(c), nella quale i nodi Ni e Nj possono ricevere messaggi da Nk ma non comunicare direttamente: Nj risponde a Nk , che può cosı̀ calcolare il suo hka0 , e lo ritrasmette a entrambi i nodi Ni e Nj . Una versione “simmetrica” di questa variante (vedi [19]) si ha se sia Ni che Nj rispondono a Nk e questo ritrasmette in broadcast entrambi i timestamp, cosicchè ciascun nodo è a conoscenza dei timestamp riportati dagli altri nodi. 4.1.2 Periodicità Solitamente due clock anche identici, pur avendo la stessa frequenza nominale, non hanno mai la stessa frequenza effettiva, quindi dopo un certo periodo di tempo accumuleranno un errore di fase: vi è dunque la necessità di ripetere periodicamente l’operazione di sincronizzazione. La durata dell’intervallo di tempo tra due round di sincronizzazione successivi dipende dal massimo errore di sincronizzazione tollerabile e dal drift relativo tra i due clock in oggetto. Chiamiamo la durata di questo intervallo τround , e assumiamo che essa sia composta da una prima parte in cui avviene la sincronizzazione (τsincr ) e da una seconda in cui il nodo esegue altre operazioni (non di sincronizzazione); poniamo inoltre che il massimo errore 4.2 Combinare i risultati 37 tollerato sia Etotal , il massimo errore dopo τsincr sia Esincr , e lo skew massimo sia ρmax . Allora la lunghezza massima τround sarà: Etotal − Esincr (4.1) τround ≤ ρmax Quindi la lunghezza dell’intervallo tra una sincronizzazione è tanto maggiore quanto più piccoli sono Esincr e ρmax . Algoritmi che usano la tecnica di round-trip mirano a ridurre Esincr , altri invece cercano di stimare lo skew del clock e quindi di compensare, con il risultato di avere uno skew “effettivo” ρ minore di quello reale. In alcune implementazioni, il minimo errore di sincronizzazione ottenibile con un solo scambio di messaggi è maggiore di Etotal , quindi si tenta di ridurlo con ulteriori scambi di messaggi di sincronizzazione; al limite, τsincr ≈ τround , vi è cioè sincronizzazione continua. 4.2 Combinare i risultati Cercheremo ora di combinare misurazioni successive del tempo locale di un nodo per ottenere un errore di sincronizzazione più basso. I dati di riferimento sono plottati in Figura 4.2(a): ciascun cerchietto rappresenta una stima del tempo locale hja del nodo Nj in cui avviene un evento a, che si verifica all’istante misurato nel nodo Ni come hia . 4.2.1 Regressione lineare La tecnica più usate è la regressione ai minimi quadrati; solitamente si suppone che la serie delle misurazioni sia approssimabile con un polinomio lineare di grado uno, cioè una relazione del tipo hj = α + β · hi , e si determinano i coefficienti α e β minimizzando i quadrati delle differenze tra gli hj della retta di fit e i valori misurati. Un maggior numero di campioni porta ad una stima più accurata della retta di fit, anche se richiede più memoria per la memorizzazione e un tempo maggiore per la raccolta (che si traduce in un tempo di convergenza più lungo per l’algoritmo). Il coefficiente β è la stima del drift del clock di Nj rispetto a quello di Ni , quindi la regressione lineare compensa implicitamente per il drift. Se questo è variabile nel tempo, allora la stima (la retta di fit) deve essere aggiornata periodicamente ed è opportuno calcolarla su un numero più piccolo di valori. Uno dei vantaggi di questa tecnica è che può essere calcolata a runtime aggiungendo alla stima i nuovi valori via via che vengono misurati, uno svantaggio è 38 Alle basi della sincronizzazione Figura 4.3: Combinare più misurazioni: a) Ciascun cerchietto rappresenta una stima del tempo locale hja del nodo Nj in cui avviene un evento a, che si verifica all’istante misurato nel nodo Ni come hia . la linea retta è il risultato della regressione lineare dei dati misurati, quella tratteggiata è il risultato della PLL. b) Lo stesso approccio può essere utilizzato per calcolare il lower (∇) e l’upper (∆) bound sul tempo locale di Nj . Le linee rette sono il risultato della tecnica Convex-hull. 4.3 Trattare gruppi di nodi 39 che le misurazioni vengono pesate come il quadrato delle differenze con la retta di fit, quindi valori sbagliati pesano molto e hanno una forte influenza nella determinazione di α e β. 4.2.2 Phase-locked Loop Un altro metodo per elaborare una serie di misurazioni è basato sul principio delle phase–locked loops (PLL) [16]. Una PLL controlla la pendenza della retta di fit usando un controllore proporzionale–integrale (PI), il cui output è somma di una componente proporzionale all’ingresso e di una componente proporzionale all’integrale dell’ingresso. L’ingresso in questo caso è la differenza tra il valore misurato e il valore nel punto della retta di fit: se quest’ultimo è più piccolo del valore misurato, la pendenza diminuisce, altrimenti aumenta. Il vantaggio principale del PLL è che richiede molta meno memoria della regressione lineare perché deve memorizzare molti meno dati (non l’intera serie di misurazioni ma solo lo stato interno, cioè la somma dei due componenti sopracitati), il principale svantaggio è che richiede un lungo tempo per convergere. 4.2.3 Convex-hull [9] Prendiamo in considerazione Figura 4.2(b), dove sono riportati, sull’asse x gli stessi valori hi di Ni di Figura 4.2(a), e sull’asse y le stime dei limiti inferiore e superiore del tempo hj del nodo remoto Nj . Per ogni insieme di punti (limite inferiore e limite superiore) si determina il convex hull, ovvero il poligono convesso che contiene tutti tali punti , dopodichè si determina la retta che massimizza la distanza dai punti di supporto, cioè quelli per cui passa il poligono. 4.3 Trattare gruppi di nodi Le Wireless Sensor Networks sono spesso molto estese ed hanno una topologia molto più complessa dei semplici esempi visti nelle figure 4.2 e 4.1, nella quale non tutti i nodi possono comunicare con tutti gli altri: in situazioni del genere, bisogna elaborare dei meccanismi di sicronizzazione adatti a reti multi-hop. Si potrebbe considerare un livello logico di descrizione della rete in cui tutti i nodi distano 1-hop da tutti gli altri, anche se al livello sottostante questi “1-hop-link” sono composti da più tratte, ma l’efficienza degli algoritmi di sincronizzazione è direttamente collegata al ritardo in trasmissione e questo, già difficile da stimare in 40 Alle basi della sincronizzazione collegamenti single-hop, diventa ingestibile in collegamenti formati da molteplici tratte: gli algoritmi di sincronizzazione devono quindi gestire esplicitamente il problema della sincronizzazione multihop. Figura 4.4: Reti multihop: a) sincronizzazione single-hop con una serie di nodi master distribuiti nella rete, sincronizzati tra di loro con meccanismi out-of-band. b) sincronizzazione in cluster con nodi appartenenti ad entrambi i cluster, che effettuano la conversione del timestamp. c) struttura ad albero con un nodo master alla radice. d) non strutturata. 4.3.1 Sincronizzazione esterna La soluzione più semplice — evitare il problema — prevede che nella rete siano distribuiti un gran numero di nodi master, in questo caso diversi dai normali nodi della rete perchè dotati di hardware supplementare, ciascuno dei quali fa da riferimento per un certo numero di nodi che distano 1 hop da esso. Questi nodi master saranno sincronizzati sullo stesso rifermento temporale usando dei meccanismi out of band, cioè sistemi che non usano la rete stessa per scambiare le informazioni di sincronizzazione, ad esempio il GPS. 4.3.2 Clustering Si può suddividere la rete in cluster — piccoli insiemi di nodi che si trovano nello stesso dominio di broadcast; in questo modo ciascun nodo appartenente al cluster può mandare messaggi in broadcast a tutti gli altri nodi, e si può quindi utilizzare la tecnica Reference Broadcast per sincronizzare il cluster internamente. Dei nodi appartenenti a due o più cluster, che chiameremo nodi gateway, saranno sincronizzati con tutti i cluster a cui appartengono, e si preoccuperanno di convertire i timestamp dal riferimento temporale di un cluster a quello di un altro nel caso 4.3 Trattare gruppi di nodi 41 di trasmissione di dati dai nodi di un cluster a quelli di un’altro. Ovviamente la scelta delle dimensioni dei cluster è un parametro fondamentale: scegliere pochi cluster molto estesi permette di minimizzare il numero di conversioni, che sono fonte di errori di sincronizzazione, d’altra parte cluster grandi significa maggiori potenze in trasmissione, e quindi minor vita dei nodi a causa del gran consumo di energia. 4.3.3 Alberi di copertura Una delle soluzioni più usate è di costruire, con uno dei vari algoritmi noti in letteratura, un albero di copertura della rete con un nodo, che funge da master per la sincronizzazione, alla radice; i nodi sui lati saranno sincronizzati l’un l’altro con algoritmi di tipo single-hop. Dal momento che l’errore di sincronizzazione aumenta con il numero di hop di distanza dal nodo radice, è preferibile costruire alberi il più “bassi” possibile; d’altra parte se il numero di livelli dell’albero è basso, allora un nodo, la radice ad esempio, dovrà sincronizzare molti nodi del livello sottostante, e ciò si traduce in un elevato consumo di energia per i nodi posizionati più in alto nell’albero, dovuto al maggior numero di messaggi di sincronizzazione da scambiare. Nelle Wireless Sensor Network inoltre la topologia è spesso dinamica: ci sono nodi mobili che si spostano, nodi che si spengono per esaurimento della batteria e quindi spariscono, e magari vengono rimpiazzati con altri nodi che entrano a far parte della rete. Gli algoritmi devono essere capaci di aggiornare velocemente la topologia della rete, e non solo: se a cadere è il nodo radice, questo deve essere sostituito da un altro nodo senza che la rete, nel periodo di esecuzione dell’algoritmo di elezione della radice, vada fuori sincronia. Per finire, sottolineiamo che due nodi fisicamente vicini nello spazio possono trovarsi anche a molti hop di distanza nell’albero di copertura costruito dall’algoritmo di sincronizzazione: in tal caso l’errore di sincronizzazione tra essi è molto maggiore di quanto sarebbe se si fossero sincronizzati direttamente l’uno con l’altro. 4.3.4 Non strutturata Come visto nel caso della costruzione dell’albero di copertura, il routing multihop può essere interpretato come la determinazione di tabelle di routing su cui sono memorizzati i percorsi attraverso i quali passano i pacchetti diretti da un nodo 42 Alle basi della sincronizzazione ad un altro. L’approccio non strutturato invece non risolve esplicitamente questo problema, ma favorisce il passaggio delle informazioni attraverso una qualsiasi coppia di nodi che possono comunicare tra di loro. In questa maniera vengono effettuate solo sincronizzazioni tra coppie di nodi, e tali informazioni vengono “messe in comune” con l’intera rete attraverso meccanismi che variano a seconda dell’algoritmo. Uno di questi è noto come interval based synchronization: due nodi si sincronizzano e scelgono come upper e lower bound comune dei loro clock il più grande tra i lower bound e il più piccolo tra gli upper bound. Un’altra proposta simile è nota come asynchronous based diffusion [6], nella quale ciascun nodo aggiusta il proprio tempo locale alla media dei tempi locali di tutti i nodi sincronizzati: dopo un certo tempo le medie di tutti i valori della rete convergeranno verso un valore unico. Una proposta simile è fatta dall’autore di questa tesi in 6.6; in questa però il valore che viene ricavato tramite la media pesata dei valori di tutti i nodi sincronizzati della rete è il valore dello skew — cioè la differenza tra la frequenza del clock locale e quello di riferimento: in questo modo tutti i nodi della rete non sono sincronizzati con un clock reale, ma con un clock ‘virtuale’ che tutti i nodi approssimano considerando che il loro clock locale abbia uno skew rispetto a quello virtuale pari allo skew medio della rete. Essendo questi approcci completamente locali, non avendo cioè bisogno di un nodo particolare che fa da riferimento o di una qualche configurazione centralizzata, sono robusti rispetto allo spegnimento di un nodo o ad uno spostamento dei nodi stessi all’interno della rete. Al contrario gli algoritmi basati sul clustering o sull’albero di copertura richiedono che la configurazione della rete venga aggiornata ogni qualvolta un nodo si sposta o si spegne o nuovi nodi vengono inseriti nella rete. Dal momento che negli algoritimi che non prevedono una particolare struttura della rete i nodi non tentano di comunicare con un nodo in particolare, alcuni di questi algoritmi prevedono che i nodi inseriscano il proprio timestamp in tutti i pacchetti che inviano, anche se di applicazioni non legate alla sincronizzazione (tecnica di piggybacking), ad esempio [10]. In tal modo questi algoritmi risultano avere overhead nullo, in quanto per la trasmissione dell’informazione di sincronizzazione non vengono usati pacchetti dedicati ma vengono sfruttati i pacchetti che già verrebbero trasmessi per altre applicazioni. 4.4 Fonti di ritardo 4.4 43 Fonti di ritardo I ritardi (deterministici e non) nella trasmissione dei pacchetti in una Wireless Sensor Network sono spesso di ordini di grandezza più grandi della precisione richiesta per la sincronizzazione, per cui devono essere analizzati per trovarne l’origine ed eventualmente per mettere a punto delle tecniche per eliminarli o compensarli. Chiamiamo il nodo che inizia lo scambio di pacchetti sender e quello che risponde receiver. E’ molto diffusa la seguente suddivisione (vedi [30, 24], Figura 4.5), nella quale si suppone che lo stack di rete dei nodi di una Sensor Network sia suddiviso in layer come nelle tradizionali reti di calcolatori (modello ISO/OSI): Figura 4.5: Suddivisione dei ritardi nella trasmissione di un paccketto su un link wireless. 1. Send Time—quando un nodo decide di spedire un pacchetto, l’operazione deve essere schedulata e attendere il suo turno per l’esecuzione insieme agli altri task del sistema operativo. Dopodichè è richiesto altro tempo per l’assemblamento del pacchetto e la sua trasmissione dal livello applicativo al livello più basso (MAC) dello stack. Il send time è non deterministico, dipende sia dal carico del processore che dall’overhead delle chiamate al sistema operativo sottostante, e può arrivare anche a centinaia di millisecondi. 2. Access Time—dopo aver raggiunto il livello MAC, il pacchetto deve attendere per la trasmissione finchè non si libera il canale, dal momento che questo è il canale radio, che è condiviso tra tutti i nodi. Questo tempo può essere deterministico o non deterministico, a seconda del protocollo di trasmissione implementato, nel primo caso, e del traffico di rete, nel secondo caso, e varia da pochi millisecondi ad alcuni secondi. 3. Transmission Time—è il tempo necessario alla trasmissione via radio dei bit componenti il pacchetto. Questo ritardo è per la maggior parte determini- 44 Alle basi della sincronizzazione stico e può essere calcolato a partire dalla dimensione del pacchetto e dalla velocità di trasmissione. A seconda dell’implementazione della parte software del trasmettitore vi possono essere piccole variazioni dovute ai tempi di risposta agli interrupt. 4. Propagation Time—il tempo impiegato dal pacchetto per percorrere lo spazio tra il sender e il receiver. Solitamente è piccolo rispetto alle altre sorgenti di ritardo e viene considerato nullo, in realtà varia a seconda della distanza tra i due nodi, ma per distanze sotto i 300 metri è inferiore al microsecondo e la sua influenza è minima. 5. Reception Time—il tempo impiegato a ricevere i bit del messaggio e passare il pacchetto ricostruito al livello MAC. E’ uguale al Transmission Time, e i due per lo più si sovrappongono, come vediamo in Figura 5. Figura 4.6: Vediamo come — ad eccezione dello sfasamento dovuto al- la sincronizzazione dei trasmettitori – transmission time e reception time si sovrappongono. 6. Receive Time—tempo impiegato per processare il messaggio in arrivo (passaggio attraverso i layer dello stack fino a quello applicativo) e notificare all’applicazione l’avvenuta ricezione. Esistono algoritmi di sincronizzazione, come ad esempio RBS ([19]), che eliminano le incertezze su send time e access time, e con una modifica minima allo stack del sistema operativo è possibile rimuovere l’incertezza su receive time, cosicchè le uniche incertezze rimangono sui restanti tre tempi, che sono più facilmente calcolabili in quanto deterministici o quasi. La forza del protocollo RBS è proprio che permette di eliminare tutte o quasi le incertezze con modifiche minime sui livelli più bassi dello stack, e quindi è applicabile anche su hardware di uso comune, quale schede wireless per personal computer o PDA. Come fanno notare gli autori di [30], sulle piattaforme più comuni per realizzare Wireless Sensor Networks, come i mica2 o i tmote sky, si ha accesso diretto al 4.4 Fonti di ritardo 45 livello MAC, ed è quindi possibile prendere i timestamp a quel livello, subito prima della trasmissione (dopo che il chip radio ha rilevato il canale libero per la trasmissione) e subito dopo la ricezione (quando il chip radio ha ricevuto tutti i dati che compongono il pacchetto), eliminando cosı̀ l’incertezza su send, access e receive time (o meglio, l’incertezza rimane ma non influisce sulle misure in quanto i timestamp vengono presi a istanti ben definiti prima e dopo). Analizziamo più in dettaglio l’incertezza derivante dalla parziale sovrapposizione di transmission e reception time, e descriviamo nel dettaglio come avviene la trasmissione di un messaggio sul canale wireless: consideriamo un particolare punto del messaggio, ad esempio l’ultimo bit di un determinato byte, e seguiamo la sua propagazione attraverso i livelli software, hardware e physical del canale wireless dal nodo sender al nodo receiver. Per prima cosa il messaggio è trasferito pezzo per pezzo, solitamente byte per byte, al chip radio, che si preoccupa di fare l’encoding del pezzo che gli è stato mandato e generare quindi l’onda elettromagnetica corrispondente tramite l’antenna. Dopo aver trasmesso cosı̀ un pezzo, il chip radio segnala al microcontrollore che è pronto a ricevere il secondo pezzo, e cosı̀ via. L’onda cosı̀ generata si propaga nel mezzo trasmissivo ed è riconvertita in binario dal chip radio del receiver che, ogni volta che riceve un pezzo del messaggio, lo segnala al microcontrollore, il quale lo può leggere. Quindi osserviamo le seguenti ulteriori fonti di ritardo: 3a. Interrupt Handling Time—il tempo che passa tra l’istante in cui il chip radio segnala una interruzione al microcontrollore (perché ha terminato l’encoding di una porzione di messaggio ed è pronto a ricevere la successiva) e l’istante in cui il microcontrollore risponde (sostanzialmente il tempo necessario al microcontrollore per terminare l’esecuzione dell’istruzione corrente, qualche centinaio di microsecondi). Se le interruzioni sono disabilitate questo ritardo può crescere di ordini di grandezza. 3b. Encoding Time—il tempo necessario al chip radio per trasformare la porzione del messaggio “corrente” in onde elettromagnetiche: si inizia a contare dal momento in cui il chip radio segnala al microcontrollore di aver ricevuto la porzione di messaggio da encodare e trasmettere. É deterministico e nell’ordine di un centinaio di microsecondi. 5a. Decoding Time—il tempo impiegato dal chip radio lato receiver per tra- 46 Alle basi della sincronizzazione sformare il messaggio da onde elettromagnetiche alla sua rappresentazione binaria: finisce quando il chip radio segnala al microcontrollore, tramite un interrupt, che la ricezione è terminata. Questo tempo è deterministico e nell’ordine di centinaia di microsecondi, ma può variare a causa di fluttuazioni della potenza del segnale e errori nell’allineamento dei bit. 5b. Byte Alignment Time—il ritardo dovuto a un differente allineamento dei bit tra il sender e il receiver. Molto spesso prima della trasmissione vera e propria vengono scambiati dei byte di sincronizzazione e da lı̀ determinato l’offset (in bit) tra il chip radio del sender e il chip radio del receiver, che poi viene utilizzato dal receiver per correggere l’allineamento dei bytes trasmessi successivamente. Questo ritardo è deterministico e può essere calcolato dal receiver a partire appunto dal bit offset e dalla velocità di trasmissione della radio. Figura 4.7: Schematizzazione della trasmissione di un punto ideale di un messaggio attraverso gli strati software (cpu), hardware (chip radio) e fisico (antenna) lato sendere e lato receiver. La Figura 4.4 riassume i ritardi nella trasmissione di un punto ideale (ad esempio l’ultimo bit di un particolare byte del messaggio) lungo il canale wireless. Ciascuna linea rappresenta la scala temporale, ovvero il riferimento dato da un clock ideale. I punti rappresentano gli istanti in cui il punto ideale che stiamo considerando passa attraverso il livello, i triangoli sulla prima e sull’ultima riga indicano gli istanti in cui viene preso il timestamp in trasmissione e in ricezione; a seconda dell’hardware, 4.4 Fonti di ritardo 47 i timestamp vengono registrati quando il microcontrollore risponde all’interrupt del chip radio, sia lato sender che lato receiver. In alternativa si possono usare alcuni registri di compare per eliminare il tempo di gestione dell’interrupt (il ritardo con cui il microcontrollore risponde all’interrupt). Non abbiamo considerato gli effetti di particolari codifiche, come Manchester o SECDEC, o di schemi per la correzione degli errori di trasmissione, sui tempi di trasmissione: abbiamo supposto che le codifiche utilizzate in pratica siano applicate a blocchi ben definiti, e che il punto ideale considerato sia al termine di questi blocchi. Sulla piattaforma mica2, l’Interrupt Handling Time è tipicamente sui 5µs, con piccole variazioni a seconda di quanto codice viene eseguito, nella particolare implementazione, per gestire l’interruzione: nel caso di interruzioni disabilitate abbiamo rilevato anche tempi di 30µs. La somma di encoding e decoding time è tra 110µs e 112µs. Il Byte Alignment Time è compreso tra 0µs (per un bit offset pari a 0) e 365µs (per un bit offset pari a 7). Il propagation time è contenuto sotto il microsecondo. In tabella 4.1 sono riportati i vari ritardi, il loro dimensionamento, il tipo e l’origine. 4.4.1 Analisi degli errori Nel paragrafo 4.1.1 abbiamo dato un’idea iniziale di quali misurazioni vengono effettuate da due nodi che tentano la sincronizzazione, nei paragrafi seguenti approfondiremo questa analisi — mettendo in evidenza le varie fonti di ritardo che abbiamo evidenziato nella trasmissione di un pacchetto tra sender e receiver — nei due principali schemi di sincronizzazione, sender-receiver e receiver-receiver. Sender-receiver Consideriamo ancora lo schema di Figura 4.4.1, al quale affianchiamo una scala temporale “virtuale”, ovvero non dipendente dalle misurazioni del clock ne del nodo Ni ne del nodo Nj : indichiamo le misurazioni su tale scala con lettere minuscole, ad esempio ta è l’istante “assoluto” che il clock del nodo Ni rileva come ha . Il nodo Ni manda un pacchetto al nodo Nj all’istante hia (secondo il clock del nodo Ni , ta secondo la scala assoluta), il quale lo riceve all’istante hjb . Ricordiamo che hia e hjb sono misurati rispettivamente dal clock del nodo Ni e Nj . Scriviamo le seguenti due equazioni: tb = ta + S i + P i,j + Rj (4.2) 48 Alle basi della sincronizzazione Ritardo Dimensione Tipo-Origine Send, Receive 0-100 ms non deterministico, dipende dal carico del processore Access 10-500 ms non deterministico, dipende dal meccanismo di condivisione/concessione del canale Transmission, 10-20 ms Reception Propagation deterministico, dipende dalla lunghezza del messaggio < 1µs per di- stanze sotto i 300 deterministico, dipende dalla distanza tra il sender e il receiver metri Interrupt < 5µs nella mag- non deterministico, dipende se le Handling gior parte dei ca- interruzioni sono disabilitate o meno si, ma può essere anche sopra i 30µs Encoding e De- 100 − 200µs, va- deterministico, dipende dal chipset coding rianza < 2µs radio e dalle sue impostazioni Byte 0 − 400µs deterministico, può essere calcolato Alignment Tabella 4.1: Sorgenti di ritardo nella trasmissione di un messaggio. Figura 4.8: Schema Sender-receiver: analisi degli errori. 4.4 Fonti di ritardo 49 hjb = hia + S i + P i,j + Rj + Dai,j (4.3) S i sta ad indicare il tempo impiegato per spedire il messaggio (send time + access time + transmission time), P i,j è il propagation time dal nodo Ni al nodo Nj , e Rj è il tempo impiegato per ricevere il messaggio (reception time + receive time). Tutti questi tempi sono misurati in riferimento alla scala temporale ideale di cui abbiamo parlato poco fa. Dai,j si riferisce all’offset, cioè alla differenza dei clock tra il nodo Ni e il nodo Nj all’istante a. Il nodo Nj risponde al pacchetto all’istante hjc (misurato dal suo clock locale) ed è ricevuto da Ni all’istante hid (misurato dal clock locale di Ni ). Allo stesso modo possiamo scrivere: hid = hjc + S j + P j,i + Ri − Ddi,j (4.4) Si noti che Dcj,i ≈ Ddj,i = −Ddi,j . Inoltre, Dai,j può essere spezzato in due componenti come segue: i,j Dai,j = Ddi,j + RDa,d (4.5) i,j si riferisce all’errore relativo tra il clock del nodo Ni e quello del nodo dove RDa,d Nj accumulato tra ta e td , che può essere positivo o negativo a seconda di quale dei due clock va più veloce rispetto all’altro. Una descrizione di tale errore e di tutte le grandezze in gioco appena introdotte è presente in Figura 4.9. Figura 4.9: Differenze nei valori di due clock — che cominciano a contare nello stesso istante — dovuti allo skew, ovvero alla differente frequenza reale. Sottraendo 4.4 da 4.3 otteniamo: Dai,j Dbi,j i,j i,j RDa,d 2 · ∆ = S U C + P U C + RU C + RDa,d + (2 · Ddi,j ) (4.6) 50 Alle basi della sincronizzazione dove S U C , P U C e RU C indicano l’incertezza lato sender, receiver e nel tempo di propagazione. In dettaglio S U C = S i − S j , RU C = Rj − Ri e P U C = P i,j − P j,i . Il nostro scopo è calcolare Ddi,j , in quanto nell’approccio che stiamo esaminando la correzione del clock viene effettuata dopo un round-trip di messaggi, all’istante hd (che equivale al tempo “assoluto” td ). Esplicitando l’errore (non considerando dunque Ddi,j ) dall’equazione 4.6 ottengo: Errore = ∆ − Ddi,j = i,j RDa,d P UC RU C SU C + + + 2 2 2 2 (4.7) i,j dove RDa,d abbiamo visto si può determinare con una certa precisione. I restanti termini dell’equazione 4.7 possono a loro volta essere annullati o limitati (vedi 6.3 e 6.5). Receiver-receiver Nell’approccio receiver-receiver, due nodi si scambiano le informazioni temporali riguardo al messaggio che hanno ricevuto da un sender comune. Supponiamo che i due nodi Ni e Nj ricevano all’istante hib e hjc il messaggio spedito da Nk all’istante hka . Scomponendo i ritardi in maniera simile al paragrafo precedente possiamo scrivere: hib = hka + S k + P k,i + Ri + Dak,i (4.8) hjc = hka + S k + P k,j + Rj + Dak,j (4.9) Figura 4.10: Schema Receiver-receiver: analisi degli errori. Il nodo Nj spedisce il timestamp hjc al nodo Ni in un pacchetto separato, e lo stesso fa Ni con il suo timestamp hib . Sottraendo 4.8 da 4.9 ottengo: ∆ = (P k,j + P k,i ) + (Rj − Ri ) + (Dak,j + Dak,i ) (4.10) 4.4 Fonti di ritardo 51 i,j Dak,j − Dak,i = Dai,j = Ddi,j + RDa,d (4.11) i,j Errore = ∆ − Ddi,j = PDU C + RU C + RDa,d (4.12) dove PDU C rappresenta l’incertezza del tempo di propagazione tra due distinte coppie di nodi ed è PDU C = P k,j − P k,i . Notiamo subito che l’incertezza lato sender non compare nell’espressione dell’errore (eq. 4.12), quindi l’approccio receiver-receiver permette di annullare tale errore. Questa è solo una delle tecniche di cui parlavamo poche righe fa, implementate in vari algoritmi di sincronizzazione, che permettono di ridurre o eliminare una o più delle fonti di ritardo che abbiamo evidenziato. Nei prossimi capitoli esamineremo più in dettaglio alcuni algoritmi (RBS, TPSN, FTSP) e vedremo come essi mettono in pratica ottimizzazioni su queste incertezze. 52 Alle basi della sincronizzazione Capitolo 5 Tecniche di stima di skew e drift Quando non sei in grado di combattere, devi abbracciare il tuo nemico. Se ha le braccia intorno a te, non puo’ puntarti contro il fucile. Ngawang Jigme, “Sette Anni in Tibet” I nodi di una Wireless Sensor Network sono dotati necessariamente di oscillatori economici, e dunque non molto stabili. Una conseguenza del fatto che oscillatori dalla stessa frequenza nominale abbiano una frequenza reale leggermente diversa è che due nodi i cui clock partono allo stesso istante, dopo qualche tempo si trovano a segnare tempi diversi. Bisogna dunque utilizzare delle tecniche per stimare quantitativamente sia lo skew relativo di un clock, cioè la misura di quanto la frequenza di questo clock si differenzia in un dato istante da quella di un altro, sia il drif, T, cioè la misura della variabilità della frequenza stessa, per stabilire quando la stima della deriva del clock calcolata non è più corretta – ed è dunque necessaria una resincronizzazione – in modo da poter calcolare l’offset degli orologi dopo un certo periodo di tempo t e correggere quindi le letture degli orologi stessi che vengono effettuate dopo t istanti dalla sincronizzazione. Distinguiamo l’analisi sullo skew, in cui determiniamo le differenze di frequenza tra due clock e correggiamo le letture supponendo che tale differenza non cambi per un certo tempo, e l’analisi sul drift, in cui determiniamo la variabilità della frequenza, e calcoliamo l’errore sulla stima dei valori dei clock nel futuro (quella 54 Tecniche di stima di skew e drift che usiamo per la correzione di cui abbiamo parlato poche righe fa), che servirà da parametro per stabilire quando effettuare una resincronizzazione. 5.1 5.1.1 Correggere le proprie letture Definizioni Definizione 1 (Offset) Definiamo offset dell’oscillatore di un nodo Ni rispetto a quello di un nodo Nj come differenza hi − hj tra i valori segnati dai clock dei due nodi, che hanno iniziato a contare nello stesso istante, dopo un certo periodo di tempo t, dovuto allo scostamento della frequenza reale da quella nominale dei due oscillatori, scostamento dovuto a fattori ambientali (quali temperatura, umidità, pressione, tensione di alimentazione) e interni (stress interno dovuto ad uso continuato dell’oscillatore,...). Definizione 2 (Skew) Definiamo skew dell’oscillatore (derivata prima dell’offset) di un nodo Ni rispetto a quello di un nodo Nj come la differenza ḣi − h˙j della frequenza dei clock dei due nodi. Supponendolo costante, è possibile calcolare il valore del clock negli istanti futuri e dunque lo scostamento (offset) tra i clock dei due nodi in un dati istante t nel futuro. Definizione 3 (Drift) Definiamo drift dell’oscillatore (derivata seconda dell’offset) di un nodo Ni rispetto a quello di un nodo Nj come la variazione della sua frequenza di funzionamento. Se il drift fosse zero, una volta conosciuto lo skew relativo tra due nodi e l’offset iniziale dei due clock non vi sarebbe necessità di risincronizzare, dal momento che i valori futuri del clock sono predicibili. Nella realtà lo skew può essere considerato costante solo per un breve intervallo di tempo, dopodichè intervengono fenomeni di drift. Dopo l’operazione di sincronizzazione i globaltime segnati dai clock dei due nodi sono uguali, dal momento che ciascuno dei due tiene conto dell’offset iniziale del suo clock rispetto a quello dell’altro nodo, e lo aggiunge alle letture del suo clock locale per ottenere le letture del virtual clock. A causa dello skew relativo tra i due clock, dopo un certo tempo t essi divergono, quindi diventano non sincronizzati, con un 5.1 Correggere le proprie letture 55 errore che aumenta all’aumentare della distanza dall’istante di sincronizzazione. Per limitare questo errore ciascun clock si preoccuperà dunque di correggere le sue letture sottraendo al valore del suo clock locale il valore stimato dell’offset (determinato grazie al valore dello skew) al tempo t. Dal momento che la frequenza varia nel tempo, seppur di poco, anche il valore dello skew è tempovariante, e deve essere periodicamente ricalcolato. 5.1.2 Sample repository La tecnica solitamente utilizzata per stimare lo skew di un oscillatore rispetto ad un altro consiste nel prendere una serie di misurazioni e successivamente interpolarle con un polinomio che viene usato per calcolare i valori del clock negli istanti successivi. Consideriamo un nodo Ni che manda periodicamente dei pacchetti di sincronizzazione al nodo Nj : questi pacchetti contengono un timestamp hia dell’istante in cui il pacchetto viene spedito secondo il clock locale di Ni . Alla ricezione, il nodo Nj prende il timestamp dell’istante in cui riceve tale pacchetto. Ripetendo il procedimento più volte, il nodo Nj ottiene due serie di timestamp (hia , hib , . . . , hik ) (hja , hjb , . . . , hjk ) che vanno a costituire il sample repository. Le differenze tra le coppie corrispondenti di questi valori — se i due oscillatori avessero esattamente la stessa frequenza — sarebbero tutte uguali, ma a causa del fenomeno descritto poco sopra, sono diverse, solitamente crescenti. Il periodo di campionamento, S, corrisponde alla periodicità con cui Ni spedisce pacchetti a Nj : la spedizione di questi pacchetti consuma energia, d’altra parte è necessario che periodicamente questi pacchetti vengano “sostituiti” da altri più recenti in modo che Nj aggiorni il modello relativo del clock di Ni . L’operazione di ricevere un nuovo campione del sample repository ha dunque influenza sia da un punto di vista energetico (maggior consumo), sia dal punto di vista dell’errore di sincronizzazione, dal momento che campioni recenti permettono una stima più accurata del clock di Ni da parte di Nj e dunque un minor errore. Le caratteristiche dei dataset su cui si basano le considerazioni seguenti, e le modalità con cui sono stati ottenuti, sono riportate in [32], paragrafo 4. 56 Tecniche di stima di skew e drift 5.1.3 Fit polinomiale Scriviamo il modello di avanzamento dei clock dei due nodi Ni e Nj rispetto ad una scala temporale (indicata dai k): ( j hk = α j k + β j hik = αi k + β j ricavando k dalla prima equazione e sostituendola nella seconda ottengo: j hk −β j i i + βi hk = α αj = = i αi j h − ααj β j αj k γhjk + δ + βi Determinare γ e δ mi permetterà di convertire timestamp relativi al clock di Ni in timestamp relativi al clock del nodo Nj e viceversa. Dai valori del sample repository viene ricavata, tramite un qualche metodo di interpolazione, una funzione polinomiale (nel nostro caso lineare) che approssima l’andamento relativo dei due oscillatori. Solitamente il metodo usato è quello della regressione ai minimi quadrati. Metodo dei minimi quadrati Il metodo dei minimi quadrati consente di approssimare mediante una serie di funzioni una serie di dati con errore quadratico minimo; quando la serie di funzioni utilizzata impiega polinomi di primo grado si afferma che la curva di regressione è lineare. Dal momento che: ĥik = γhjk + δ ∀k posso scrivere in forma vettoriale, per un solo elemento ĥik : " # h i γ ĥi1 = hj1 1 δ e per n elementi il sistema seguente: ĥi1 j h 1 0 ... 0 ĥi2 2 j i ĥ3 = h3 1 0 . . . 0 .. .. .. . . .. . . . . . j i ĥn hn 1 0 . . . 0 hj1 1 0 ... 0 γ δ 0 .. . 0 (5.1) 5.1 Correggere le proprie letture 57 So che nella realtà ĥik 6= hik , quindi definisco ek = (ĥik − hik ). Riprendendo l’Equazione 5.1, e chiamando Ā la matrice quadrata, b̄ il vettore dei campioni (hi1 , . . . , hin ) e x̄ il vettore delle incognite, posso scrivere: Āx̄ − b̄ = ē (5.2) dove ĥi1 − hi1 .. ē = . ĥin − hin (5.3) Scopo della regressione ai minimi quadrati è calcolare: min kēk2 x̄ dove kēk2 = n X (ek )2 k=1 Ricavo dunque x̄. Premoltiplico entrambi i membri di 5.2 per Ā∗ : Ā∗ Āx̄ = Ā∗ (b̄ + ē) x̄ = (Ā∗ Ā)−1 Ā∗ (b̄ + ē) Chiamo i componenti di x̄ = (γ, δ) ricavati rispettivamente skew e offset. É quindi semplice, noto il valore del clock di un nodo Ni all’istante t, hit , calcolare il valore all’istante t + 1: hit+1 = hit + skew · S dove S è la durata del periodo di sincronizzazione e il secondo termine è l’“offset” del nodo in questione rispetto a quello scelto come riferimento accumulato nel tempo S. In questo modo riusciamo “isolare” dalle letture del clock locale la parte dovuta alla differenza di frequenza e, sottraendola, ottenere delle letture “corrette”, almeno nel breve periodo, o finchè l’andamento della frequenza non varia significativamente. 5.1.4 Resincronizzazione periodica Naturalmente l’approssimazione della retta, per quanto fedele al reale andamento del clock, è pur sempre un’approssimazione: ci si aspetta dunque che dopo un certo periodo di tempo il valore reale della frequenza si discosti da quello previsto 58 Tecniche di stima di skew e drift dalla retta di fit determinata con la tecnica appena descritta, proprio perchè vi sono fenomeni di drift. Vi è dunque necessità di una resincronizzazione periodica, cioè di ricalcolare periodicamente la retta di fit (determinare un nuovo skew e un nuovo offset). Questo permette di mantenere sempre sotto una certa soglia l’errore di sincronizzazione, ma richiede lo scambio continuato di messaggi di sincronizzazione, che consumano molta energia. Si deve tentare dunque di determinare il polinomio di fit che minimizza l’errore anche dopo un lungo periodo di tempo, in maniera da aumentare il più possibile l’intervallo di sincronizzazione, ma non solo, individuare anche altri parametri su cui agire per migliorare l’efficienza, ad esempio l’intervallo ottimo di resincronizzazione che mantiene l’errore di predizione sotto ad una soglia accettabile. 5.2 Calcolare il periodo di campionamento Abbiamo visto come un nodo può tentare di correggere le letture del suo clock per compensare la diversa frequenza del suo oscillatore rispetto a quella di un altro nodo. Cerchiamo adesso una tecnica per determinare il periodo ottimo tra due sincronizzazioni, cioè il più grande intervallo di tempo tra due scambi di pacchetti di sincronizzazione (S, intervallo di campionamento) che ci permette di mantenere l’errore sotto una certa soglia. 5.2.1 Modello Riprendiamo il modello relativo dei due oscillatori visto prima hj = δk + γk hi + (5.4) dove indica sia errori di misura che dovuti a fattori ambientali, o che comunque non sono modellizzati dal polinomio. Il nostro problema di ottimizzazione è dunque cosı̀ definito: Dati Gli hik , hjk contenuti nel sample repository Trovare W (window size), K (grado del polinomio interpolatore) e S (intervallo di campionamento) Tali che Sia massimizzato S, per Ep < Emax (dove Ep è l’errore di predizione, ovvero la differenza tra il valore predetto dal modello e il valore misurato del successivo campione) 5.2 Calcolare il periodo di campionamento 59 Tale errore è calcolato al passo immediatamente successivo, cioè dato un nuovo campione al passo k e aggiornata con esso la stima, si calcola la predizione per il campione al passo k + 1 e si effettua la differenza tra tale predizione e il campione misurato al passo k + 1. Analizziamo ora in dettaglio le relazioni che intercorrono tra i parametri W , S e K, prima separatamente e poi assieme. Assumiamo per ora che K = 1, dal momento che abbiamo empiricamente osservato — ed è ipotesi diffusa in letteratura — che, per brevi periodi di tempo, l’approssimazione lineare per l’andamento del clock è sufficiente. 5.2.2 Numero di campioni Nell’immagine 5.2.2 mettiamo in relazione, fissati S e K, l’impatto delle variazioni di W sull’errore. Notiamo che esiste un valore ottimo W ∗ , in corrispondenza del quale l’errore di predizione è minimizzato. Il fatto che per valori di W minori o maggiori di W ∗ l’errore cresca visibilmente ci fa capire l’importanza di questo parametro. Per W < W ∗ non ci sono abbastanza campioni disponibili per ottenere un modello accurato del clock, mentre per W > W ∗ il drift probabilmente non è nullo nell’intervallo di tempo in cui sono presi i campioni, quindi il numero di gradi di libertà del modello (2, nel caso lineare) non è sufficiente a riprodurre la dinamica del drift. 5.2.3 Periodo di campionamento Osserviamo ora la relazione tra il numero di campioni usati nella regressione, W, e il periodo di campionamento. Osserviamo dalla Figura 5.2.3, che abbiamo ricavato da test di laboratorio [32], che W* è circa 4 per un periodo di campionamento attorno ai 2 minuti, e diventa 25 per un periodo intorno ai 15 secondi. La cosa più importante però è che, per periodi superiori a 2 minuti, la W* è il minimo, cioè due, quindi se usiamo periodi di campionamento molto lunghi è inutile, ai fini di migliorare il polinomio che otteniamo con l’interpolazione, usare un numero maggiore di campioni. Notiamo inoltre, vedi Figura 5.2.3, che l’errore di predizione aumenta monotonicamente con l’aumentare del periodo di campionamento. Questo ci fa capire che nella nostra ottimizzazione dovremo cercare un tradeoff tra periodo di cam- 60 Tecniche di stima di skew e drift Figura 5.1: Impatto del numero di campioni usato per la predizione sull’errore di predizione. Figura 5.2: Relazione tra W ottima e periodo di campionamento. 5.2 Calcolare il periodo di campionamento 61 pionamento ed errore ammesso: intervalli di campionamento lunghi ci permettono di consumare meno energia ma portano ad un errore più elevato, e viceversa. Figura 5.3: Relazione tra errore di predizione e periodo di campionamento. 5.2.4 Time Window Introduciamo una nuova metrica, la cosiddetta time window, corrispondente al prodotto di window size e periodo di campionamento. L’esistenza di una time window (T) ottima implica che se la stima è fatta dentro quel periodo di tempo, allora l’errore su di essa è minimo. Se ad esempio abbiamo una time window pari a 8, ogni stima effettuata con campioni precedenti gli otto minuti non migliora l’errore della predizione. D’altra parte, per periodi di campionamento molto alti il tempo entro cui sono stati presi i campioni del sample repository è necessariamente più grande di T; in questo caso il valore minimo di W, cioè K+1, è l’ottimo. Facciamo notare ancora una volta che per trovare un polinomio interpolatore di grado K abbiamo bisogno di almeno K+1 campioni. Se inoltre è nota T, è semplice calcolare la W*, cioè il numero ottimo di campioni da usare per la regressione, come T ∗ W = max K + 1, S 5.2.5 Errore della predizione Data una time window di n campioni, (hik , hjk ), possiamo calcolare il tempo del nodo Nj in corrispondenza di un tempo al nodo Ni , usando la regressione ai minimi quadrati in 5.4 come: ĥj = βˆ0 + βˆ1 hi 62 Tecniche di stima di skew e drift Figura 5.4: Relazione tra time window ottima e periodo di campionamento. usando la teoria della regressione, possiamo costruire un intervallo di confidenza (1 − α) per questa misura: ĥj ± δ dove δ = t(1−α)/2,n−2 · SD(ĥj ) (5.5) Il primo termine del prodotto nell’Equazione 5.5 è il quantile superiore della distribuzione t di Student con n − 2 gradi di libertà (numero dei campioni meno uno), e il secondo termine è la deviazione standard del valore calcolato dal modello. Indichiamo questo prodotto, stima dell’errore di predizione (Ep ), con δ. Abbiamo usato un intervallo di confidenza del 95% per stimare δ, dal momento che questo è il valore tipico usato in letteratura per gli errori, come il nostro , che hanno distribuzione gaussiana. 5.2.6 Accuratezza della stima Se il termine di errore, , ha una distribuzione normale, allora gli intervalli di confidenza sono quelli dell’Equazione 5.5. Ci sono però molte variabili “lasciate fuori” dall’Equazione 5.4, ad esempio temperatura e umidità, di cui non si tiene 5.2 Calcolare il periodo di campionamento 63 conto per evitare che lo stimatore diventi troppo complesso per essere eseguito sul microcontrollore di un nodo. Una forma più appropriata del modello potrebbe essere: hj = f (hi , x̄) + ∗ (5.6) dove f (·) è una qualche funzione che dipende da hi e dalle condizioni ambientali, qui rappresentate del vettore di variabili x̄, mentre ∗ è una variabile aleatoria gaussiana a media nulla. Volendo usare un modello comprensivo anche dei termini di errore che nell’Equazione 5.4 avevamo riassunto in , l’intervallo calcolato nell’Equazione 5.5 non è più corretto. Possiamo invece decomporre l’errore di predizione in: hj − ĥj = f (hi , x̄) + ∗ − (δ̂ + γ̂hi ) h i = ∗ + (δ ∗ + γ ∗ hi ) − (δ̂ + γ̂hi ) + f (hi , x̄) − (δ ∗ + γ ∗ hi ) h h i i = ∗ + E ĥj − ĥj + f (hi , x̄) − (δ ∗ + γ ∗ hi ) (5.7) h i dove δ ∗ = E δ̂ e γ ∗ = E [γ̂] sono le aspettazioni dei valori stimati. Ricordiamo che δ ∗ e γ ∗ si ottengono dalla soluzione dell’equazione dei minimi quadrati, sostituendo al modello polinomiale la f (hi , x̄). I primi due termini a destra nell’Equazione 5.7 sono usati per calcolare la deviazione standard che compare nell’intervallo di confidenza (Equazione 5.5): il primo è un errore che non possiamo eliminare, e il secondo la varianza nelle nostre stime (la differenza tra una variabile aleatoria, ĥj , e la sua aspettazione). L’ultima espressione tra parentesi è nota come bias e non è determinabile senza conoscere la f (·). Se ignoriamo il bias, i nostri intervalli di validità non soddisfano le proprietà di inclusione previste. In letteratura ci sono varie tecniche per correggere il bias, molte delle quali sono computazionalmente molto onerose. Dal momento che noi dobbiamo mantenere il calcolo più semplice possibile, scegliamo l’approccio più semplice, cioè ampliare questi intervalli, introducendo un fattore di scala, ∆: h i ĥj ± ∆ · t(1−α)/2,n−2 · SD(ĥj ) (5.8) 64 Tecniche di stima di skew e drift 5.2.7 Fattore di scala Più formalmente, il fattore di scala ∆ è definito come il rapporto tra l’errore di predizione corrente, Ep , e la stima dello stesso ottenuta dall’Equazione 5.5, δ: ∆= Ep δ (5.9) La Figura 5.2.7 presenta il grafico della distribuzione di probabilità di ∆, e può essere usata per decidere che ∆ usare in funzione di quanto x% dell’errore di predizione vogliamo includere negli intervalli. Ad esempio, scegliendo ∆ = 6 gli intervalli includeranno il 90% degli errori mentre scegliendo ∆ = 2 solo il 60%. Chiamiamo d’ora in poi questo x% cut-off threshold e lo indichiamo con λ. Analizziamo ora l’impatto della variazione di condizioni ambientali sul fattore di scala, calcolando la distribuzione di probabilità per vari insiemi di dati e vari periodi di campionamento. Notiamo che il valore di ∆ aumenta all’aumentare del periodo di campionamento (per una data λ), come ci si aspetta visto l’andamento dell’errore in relazione al periodo di campionamento. ∆ è anche risultato quasi costante in condizioni ambientali diverse (temperatura e umidità, cioè con esperimenti effettuati all’aperto e al chiuso a diverse temperature ambientali): questo è molto importante in quanto ci permette di non dover stimare nuovamente il parametro ogni volta che effettuiamo la messa in opera di una Wireless Sensor Network in una differente condizione ambientale. Figura 5.5: Distribuzione di probabilità per ∆ 5.2 Calcolare il periodo di campionamento 5.2.8 65 Calcolo dei parametri a runtime Determinare i parametri La maniera più semplice per determinare i parametri necessari a stabilire il periodo di sincronizzazione, cioè T e ∆, a runtime è una fase di inizializzazione del sistema. Dal momento che il fattore di scala varia di poco a seconda dell’ambiente, questa inizializzazione può anche essere fatta non sul campo ma in fase di produzione dell’hardware, in maniera da diminuire il consumo energetico; è comunque necessaria una fase di inizializzazione “sul campo” per calcolare T . In questa fase, vengono raccolti dei campioni di dati come riportato nel Paragrafo 5.1.2 e questi vengono elaborati come descritto nei Paragrafi 5.2.3, 5.2.4 e 5.2.6. Questo approccio confida nel fatto che T e ∆ abbiano una distribuzione stazionaria nel tempo cosicchè i valori determinati nella fase di inizializzazione valgano per un lungo periodo di tempo. Descrizione del protocollo Possiamo dunque abbozzare un protocollo di sincronizzazione che tenta di calcolare ripetutamente l’intervallo di campionamento in maniera che l’errore di sincronizzazione rimanga entro le specifiche. Lo pseudo-codice dell’algoritmo è il seguente: 1. Calcolare W* = max(K+1, T/S) 2. Trovare(β̂0 , β̂1 ) usando il valore W ∗ calcolato 3. Calcolare δ con l’Equazione 5.5 4. trovare Ep = ∆ · δ 5. if (Ep < [Emax · ηlow ]) S = S · M IM Dinc elseif (Ep > [Emax · ηhigh ]) S = S/M IM Ddec 6. if (S < Smin ) S = Smin elseif (S > Smax ) S = Smax Figura 5.6: Pseudocodice per l’algoritmo che stima a runtime il periodo di campionamento. L’algoritmo parte calcolando la W ∗ per un dato periodo di campionamento S. 66 Tecniche di stima di skew e drift Poi si calcola il ĥj stimato tramite il modello, e successivamente l’errore di predizione δ è scalato usando ∆. Stabiliamo inoltre due soglie entro cui riteniamo accettabile l’errore di predizione. Se l’errore è al di sotto della soglia inferiore, l’intervallo di campionamento viene incrementato moltiplicandolo per una costante (M IM Dinc , solitamente 2), se l’errore è al di sopra della soglia superiore l’intervallo di campionamento viene diviso per una costante (M IM Ddec , anch’essa solitamente 2). Se l’errore è nell’intervallo di validità determinato (tra le due soglie) allora l’intervallo di campionamento S rimane invariato. Alla fine viene comunque fatto un controllo se S è compreso tra [Smin , Smax ], per evitare che esso non cresca o diminuisca senza limiti. Il motivo per cui vengono usate costanti moltiplicative nell’adattamento dell’intervallo di campionamento S è duplice: in primo luogo questo permette una convergenza rapida dell’algoritmo, e quindi un risparmio di energia per la trasmissione via radio dei pacchetti di sincronizzazione; in secondo luogo è un metodo matematicamente molto più semplice da gestire di quello esponenziale, che garantirebbe comunque una alta velocità di convergenza ma sarebbe più complesso computazionalmente da gestire sull’hardware limitato che troviamo a bordo dei nodi. L’uso di costanti additive/sottrattive, pur mantenendo la semplicità richiesta, è sconsigliato perché converge molto più lentamente. Capitolo 6 Algoritmi di sincronizzazione Segal’s Law: A man with one clock knows what time it is. A man with two clocks is never sure. Tom Van Baak: But a man with three clocks is more sure than a man with two clocks. Dopo avere affrontato e risolto le problematiche fondamentali della sincronizzazione, cioè come ottenere letture di clock remoti, come minimizzare le incertezze nello scambio di pacchetti, e come quantificare l’errore nella predizione dei valori del clock in modo da calcolare il periodo di resincronizzazione, descriviamo operativamente gli algoritmi più diffusi in letteratura. proponiamo inoltre, nel paragrafo 6.6, un nuovo algoritmo, basato su FTSP ma con un metodo innovativo di calcolo distribuito dello skew, che chiamiamo Average Timesync. Infine presentiamo i risultati degli esperimenti effettuati riguardo agli oscillatori dei tmote sky e i test comparativi degli algoritmi FTSP e Average su tali motes. 6.1 Come valutare le prestazioni Vi sono molti modi per misurare le prestazioni di un algoritmo di sincronizzazione: errore di sincronizzazione tra due nodi, valore medio o massimo sui nodi della rete o su una percentuale di essi. Si può valutare anche il tempo di convergenza dell’algoritmo. Anche la topologia della rete e — nel caso di simulazioni — il modello usato per il canale trasmissivo, per i ritardi introdotti nei vari layer del protocollo, influiscono notevolmente sui risultati e dunque sulla valutazione delle prestazioni dell’algoritmo. 68 Algoritmi di sincronizzazione Abbiamo visto che ad un certo istante t in una sensor network ciascun nodo ha un suo valore del globaltime, che chiamiamo ci (hi (t)). Nel caso di sincronizzazione interna la precisione istantanea p(t) è definita come la differenza massima tra le stime del globaltime di due nodi: p(t) = max ci (hi (t)) − cj (hj (t)) i,j Alcuni autori usano la deviazione standard di tutti i ci (hi (t)) come misura della precisione istantanea all’istante t. Nel caso di sincronizzazione esterna invece la precisione istantantea è definita come: p(t) = max ci (hi (t)) − t i dove t, tempo fornito dal riferimento esterno, ha la stessa unità di misura e scala di ci (hi (t)). La precisione può anche essere definita come l’errore medio o massimo sul 90% (o 99%, ecc...) dei nodi con il più piccolo errore di sincronizzazione. Tale precisione istantanea ovviamente varia nel tempo; come precisione finale P si sceglie solitamente il massimo delle p(t) per tutti i t considerati. Alternativamente si puà considerare la p(t) media. È chiaro che tale precisione migliora col passare del tempo fino ad un istante in cui si stabilizza attorno al valore massimo raggiungibile: si usa rilevare la precisione P in questo particolare istante, chiamato steady state. Molti autori considerano come metrica anche il tempo di convergenza, cioè il tempo necessario all’algoritmo, dal momento in cui viene avviato, per raggiungere lo steady state corrispondente ad una data precisione. 6.2 LTS Il protocollo Lightweight Time Synchronization [33] è una sincronizzazione pairwise che non necessita di un beacon node, come la RBS, per sincronizzare due nodi. Si basa sulla determinazione del round trip time del pacchetto per calcolare l’offset tra i clock dei due nodi: 1. Il nodo Ni trasmette al nodo Nj il suo timestamp hia (lettura del clock locale) 2. Il nodo Nj registra il timestamp hjb dell’istante di ricezione del pacchetto. 6.2 LTS 69 Questo sarà hia + D + d, dove D è il tempo di trasmissione del pacchetto 1 tra i due nodi mentre d è l’offset tra i due clock. 3. Il nodo Nj trasmette un secondo pacchetto al nodo Ni , contentente hjb . Il timestamp di spedizione di questo pacchetto è hjc . 4. Il secondo pacchetto viene ricevuto da Ni all’istante hid = hjc + D − d. Il nodo ni calcola d = 21 ((hjb − hia ) − (hid − hjc )) e D = 21 ((hjb − hia ) + (hid − hjc )). 5. Ovviamente è necessario un terzo pacchetto per comunicare l’offset d calcolato anche al nodo Nj . L’ipotesi fondamentale alla base di questo metodo è che i due tempi di viaggio, dei pacchetti da Ni a Nj e viceversa, siano uguali. Nella pratica tale ipotesi non è sempre verificata, e quindi vengono introdotti degli errori (vedi Paragrafo 4.4). Nel prossimo paragrafo proporremo una soluzione che non si basa su tale ipotesi. Figura 6.1: Scambio di pacchetti nella sincronizzazione tra coppie in LTS. 6.2.1 Prestazioni Gli autori di [33] riportano risultati di simulazioni efettuate con Omnet++, un simulatore ad eventi discreti, su una rete di 500 nodi disposti in una griglia quadrata. Il protocollo MAC era simulato dando ad ogni trasmissione una certa probabilità di successo, mentre il ritardo in trasmissione e ricezione era modellato come una variabile aleatoria Gaussiana con media 0,1ms e deviazione standard σ = 11µs. Le precisioni ottenute nelle sincronizzazioni tra coppie di nodi sono nell’ordine del centinaio di microsecondi, ed è evidenziato che la precisione ottenuta decresce all’aumentare della profondità dello spanning tree della rete; in particolare si nota un minore errore di sincronizzazione nelle reti suddivise in più cluster “coperti” da 1 Riassume tutte le fonti di ritardo analizzate nel Capitolo 4, se il timestamping non è effettuato al livello MAC. 70 Algoritmi di sincronizzazione spanning tree “bassi”, che comunicano tra di loro, rispetto alle reti coperte da un unico spanning tree a molti livelli. Questo comportamento è molto significativo e verrà tenuto in considerazione per lo sviluppo algoritmi di sincronizzazione “distribuita” su larghe reti multihop, dove cioè il concetto di “nodo che dà il riferimento di tempo” o è replicato più volte sulla rete (TPSN con vari nodi radice), oppure è distribuito (come il nostro Average Timesync). 6.3 RBS 6.3.1 Single-hop L’algoritmo Reference Broadcast Synchronization, [19] a differenza del precedente, prevede la presenza di un beacon node e di due o più nodi che si sincronizzeranno tra di loro. Il funzionamento è il seguente: 1. Il beacon node spedisce un pacchetto in broadcast, che viene ricevuto dai due nodi Ni e Nj nello stesso istante. 2. Ciascun nodo che riceve il pacchetto prende un timestamp dell’istante di ricezione secondo il suo clock locale (hir e hjr ). 3. I nodi scambiano i timestamp di ricezione. In questo modo ciascun nodo conosce la coppia (timestamp locale, timestamp remoto) per lo stesso istante, e può calcolare l’offset tra il suo clock e quello dell’altro nodo. Questo metodo funziona anche per un numero n di nodi maggiore di 2. Possiamo aumentare la precisione delle misurazioni semplicemente ripetendole più volte e mediando i risultati: 1. Il beacon node invia in broadcast m pacchetti numerati. 2. Ciascuno degli n nodi registra i timestamp degli istanti in cui questi pacchetti sono ricevuti. 3. I nodi scambiano i timestamp di ricezione. 4. Ciascun nodo calcola l’offset del suo clock locale rispetto a quello degli altri nodi facendo la media tra gli offset calcolati in corrispondenza di ciascun 6.3 RBS 71 pacchetto. Dati n il numero dei nodi, m il numero dei pacchetti spediti, hib il valore del clock di Ni nell’istante in cui riceve il broadcast b, m Offset[i, j] = 1 X j (hk + hik ) m ∀i ∈ n, j ∈ n (6.1) k=1 Questa soluzione fornisce una sincronizzazione istantanea, suppone che lo skew dei clock sia nullo, cioè che essi procedano esattamente alla stessa frequenza. Nella realtà dopo un certo periodo di tempo l’offset sarà diverso da quello calcolato. Il seguente algoritmo tiene conto dello skew tra i due nodi: 1. Il beacon node invia in broadcast m pacchetti numerati. 2. Ciascuno degli n nodi registra i timestamp degli istanti in cui questi pacchetti sono ricevuti, e tramite regressione lineare trova una retta che fitta questi valori. La pendenza della retta stessa ci dà un’approssimazione dello skew relativo tra il clock del nodo e quello del beacon node. e a questo punto ciascun nodo può convertire, con una certa approssimazione, un suo timestamp in un timestamp secondo il clock locale del beacon node. Estendiamo la procedura nel modo seguente: 3. Ciascun nodo rispedisce al beacon un pacchetto con il valore dello skew e di un punto sulla retta. La spedizione di questi pacchetti è diluita nel tempo in modo da evitare collisioni. 4. Il beacon compone un pacchetto con tutte le pendenze di tutti i nodi della rete, e lo rispedisce in broadcast. 5. Ciascun nodo ora riesce ora a calcolare lo skew relativo del suo clock rispetto ad un qualsiasi altro nodo della rete, conoscendo il proprio skew rispetto al beacon e quello degli altri nodi rispetto al beacon. 6.3.2 Multi-hop Vi sono due differenti soluzioni per estendere questo algoritmo a reti multi-hop. La più semplice suppone che vi siano più beacon che comunicano tra di loro e che ogni nodo sia nel broadcast range di almeno uno di questi beacon node (cluster). Ciascun beacon node scambia con gli altri beacon le informazioni riguardo agli skew dei nodi appartenenti al proprio cluster: se riceve gli skew relativi tra un 72 Algoritmi di sincronizzazione cluster di nodi e un beacon Nu , li converte in skew relativi riferiti a se stesso (dal momento che conosce lo skew tra se stesso e il beacon Nu ) e li ritrasmette in broadcast ai nodi del proprio cluster. Questo approccio funziona ma ha uno svantaggio nella grande quantità di dati che devono venire trasmessi. Figura 6.2: RBS multihop: i beacon node (B1 . . . B4 ) sono nello stesso broadcast range (i cerchi) e possono scambiarsi i valori di skew dei clock che appartengono al proprio cluster. I nodi (N1 . . . N1 4) del cluster invece possono comunicare solo tra di loro e con il beacon node, non con i nodi ne’ con i beacon degli altri cluster. La seconda soluzione si basa su una sorta di gerarchizzazione della rete su più livelli, e sull’esistenza di nodi che appartengano ad almeno due livelli, ed è sviluppata nel dettaglio nel paragrafo 6.4. 6.3.3 Prestazioni Esistono varie implementazioni di RBS principalmente su hardware di classe consumer, come palmari Hewlett-Packard iPaq, ma anche su motes mica [19]. I risultati in termini di errore di sincronizzazione sono di 6, 29 ± 6, 45µs (intervallo di confidenza del 95%) nel primo caso, con un traffico di rete basso, ovvero gli unici pacchetti scambiati dai nodi erano quelli scambiati per la sincronizzazione. Nel caso di alto traffico di rete, l’errore è risultato maggiore, 8, 44 ± 28, 53µs, principalmente a causa della perdita di un certo numero di pacchetti. La maggior parte dell’errore è dovuta a jitter nel processing dei pacchetti nel motes ricevente, dal momento che il timestamping veniva effettuato in userspace e non a livello kernel. Usando un timestamping a livello del kernel, l’errore si riduce considere- 6.4 TPSN 73 volmente, a 1, 85 ± 1, 28µs [19]. Si suppone che l’errore dell’ordine del microsecondo sia migliorabile utilizzando clock superiori a quello da 1Mhz fornito dall’oscillatore dell’iPaq. Sottolineiamo che in queste prove non si è tenuto conto dell’alto overhead dell’algoritmo (e dunque del dispendio energetico per la trasmissione di innumerevoli messaggi). 6.4 TPSN L’algoritmo Time-synchronization Protocol for Sensor Network (TPSN) [30] si compone di due fasi. Nella prima si crea una gerarchia tra i nodi della rete, identificando un nodo radice a livello zero e assegnando un livello a tutti gli altri nodi, in modo che ciascun nodo possa comunicare con un solo nodo al livello precedente; chiamiamo questa fase “level discovering phase”. Nella seconda, un nodo a livello i si sincronizza con un nodo a livello i − 1, partendo dai nodi al livello uno (che si sincronizzano col nodo radice) e via via scendendo nell’albero; chiamiamo questa fase “synchronization phase”. 6.4.1 Level discovering In questa fase il nodo radice, che è fisso e ha livello 0, inizia a mandare in broadcast dei pacchetti chiamati level discovering, contenenti l’identità del sender e il numero del livello a cui appartiene. I nodi vicini ricevono il pacchetto, settano il proprio livello ad una unità in più rispetto al livello ricevuto, e mandano a loro volta un pacchetto level discovering: i nodi che hanno già un livello scartano tutti i successivi pacchetti di level discovering che ricevono, per cui dopo un certo tempo ciascun nodo avrà un livello assegnato. Ovviamente se nella rete esistono dei nodi che sono sincronizzati esternamente, ad esempio con un ricevitore GPS, è bene che essi agiscano da nodo radice; in questo algoritmo devono essere settati manualmente come nodo radice. Esistono dei protocolli di sincronizzazione specifici per reti di strumenti di misura, come l’IEEE 1588 [5], nei quali l’algoritmo di elezione a root si basa sulla valutazione della precisione e accuratezza dei clock di certi particolari nodi, suddividendoli in varie classi ai quali è associato uno stratum number, dagli orologi atomici al cesio fino ai comuni oscillatori al quarzo. Per una serie di motivi può accadere che un nodo non riceva un pacchetto di level discovering, per cui risulterebbe non appartenere a nessun livello e quindi non 74 Algoritmi di sincronizzazione potrebbe prendere parte alla fase di sincronizzazione; in tal caso, se dopo un certo tempo dal boot il nodo non ha ancora ricevuto un pacchetto di level discovering, inizia lui stesso il level discovering: in tal caso i suoi vicini rispondono indicando il proprio livello e il nodo entra anch’esso a far parte della rete. 6.4.2 Synchronization In questa fase si effettua la sincronizzazione a coppie, secondo il paradigma SenderReceiver del par. 4.4.1, lungo i lati dell’albero creato nella fase precedente. L’implementazione di [30] si limita alla soluzione più semplice (usata anche dall’algoritmo LTS) di non considerare la deriva dei due oscillatori durante il tempo di andata e ritorno dei pacchetti, e calcolare cosi l’offset dei clock dividendo per due il round-trip time. Il nodo radice inizia la sincronizzazione inviando una richiesta di sincronizzazione che viene ricevuta da tutti i nodi al livello 1. Dopo averla ricevuta ciascun nodo di tale livello si pone in sleep mode per un tempo casuale, in modo da evitare di doversi contendere il mezzo per effettuare la sincronizzazione: successivamente, dopo che questo tempo casuale sarà passato, i nodi si risveglieranno uno ad uno e si sincronizzeranno con la radice. Ovviamente i messaggi scambiati tra nodo e radice per la sincronizzazione saranno ricevuti anche da qualche nodo al livello 2, dal momento che ciascun nodo al livello 1 ha almeno un nodo al livello due tra i suoi vicini. Questi nodi di livello 2, che si accorgono che il nodo “padre” sta sincronizzandosi, si pongono in sleep mode per un tempo casuale, dopodichè si svegliano e iniziano una sessione di sincronizzazione proprio con il nodo di cui avevano “ascoltato” i messaggi, che suppongono nel frattempo abbia completato la sincronizzazione con il nodo radice. Questa operazione si ripete per ciascun livello successivo, i nodi di livello 1 sincronizzano cioè quelli di livello 2, e cosı̀ via, fino a che tutti i nodi sono sincronizzati. Dal momento che in una sensor network i disturbi in trasmissione sono frequenti, per evitare al massimo collisioni si introduce, oltre a tutte le attese random per evitare di contendersi il mezzo, un acknowledge su ogni pacchetto trasmesso. 6.4.3 Prestazioni Gli autori hanno implementato TPSN su un testbed di motes mica2, e misurato sperimentalmente l’incertezza lato sender media (che non è rimossa dall’approc- 6.5 FTSP 75 cio sender-receiver usato in questo algoritmo), quantificandola in 0, 62µs in media, dunque trascurabile rispetto al valore assoluto dell’errore di sincronizzazione. Hanno poi quantificato l’errore di sincronizzazione medio in 16, 9µs, il massimo osservato in 44µs [30]: considerando che RBS è stato implementato su un testbed di iPaq, che hanno un clock molto più stabile dei motes, si conclude che TPSN generalmente migliora di due volte la precisione ottenibile con RBS sullo stesso hardware (a condizione che venga effettuato il timestamping a livello MAC). Nel caso multihop l’errore medio si alza a 23 − 24µs per distanze sopra i 3 hop, e sostanzialmente si stabilizza su questo valore al crescere della distanza: in generale comunque ci saremmo aspettati che l’errore crescesse almeno linearmente all’aumentare della distanza. 6.5 6.5.1 FTSP Single-hop Questo algoritmo [24] sincronizza più nodi che si trovano nel broadcast range del nodo radice con un unico messaggio. Questo utilizza il timestamp dell’istante di spedizione secondo il clock del nodo radice, registrato al livello MAC e incluso nel messaggio stesso, e il timestamp dell’istante di ricezione secondo il clock del nodo che si sincronizza, preso anch’esso al livello MAC. Dal momento che per piccole distanze (si suppone che il broadcast range della radice sia piccolo per le solite limitazioni di risparmio energetico imposte dalla sensor network) il tempo di propagazione è talmente piccolo da poter essere trascurato, si suppone che i due timestamp sopracitati si riferiscano al medesimo istante temporale, per cui questa coppia di timestamp (a cui ci riferiamo come synchronization point) mette in relazione i clock dei due nodi. Ovviamente la sincronizzazione puntuale non è sufficiente, bisogna correggere per lo skew degli oscillatori dei nodi, e ciò viene fatto registrando più synchronization point in una tabella e determinando poi, tramite regressione lineare, una retta che ne approssima l’andamento. Se si suppone che la deriva degli oscillatori sia monotona — e che l’offset tra i due clock cresca linearmente — (cosa che vedremo nel paragrafo 6.7 è verificata) possiamo determinare a quanto ammonta la deriva del clock in un istante nel futuro, e aggiornare dunque l’offset misurato senza necessità di scambiare nuovi messaggi di sincronizzazione. Il funzionamento di questo algoritmo si basa sulla possibilità di prendere i 76 Algoritmi di sincronizzazione timestamp in ricezione e trasmissione al livello MAC, in modo da non risentire delle incertezze dovute allo scheduling del sistema operativo ed all’attesa che si liberi il canale trasmissivo 2 , e sull’assunto che il tempo di propagazione sia trascurabile; quest’ultima ipotesi è verificata nel caso di distanza coperta bassa rispetto alla velocità di propagazione del segnale. D’altra parte si può compensare per il tempo di trasmissione sottraendo al secondo timestamp un valore che tiene conto della dimensione del messaggio trasmesso e della velocità di trasmissione. 6.5.2 Multi-hop L’algoritmo appena descritto può essere esteso a reti multi-hop: il nodo radice sincronizza i nodi presenti nel suo broadcast range, e i nodi sincronizzati a loro volta effettuano il broadcast non del valore del loro clock locale ma della stima che hanno del valore clock del nodo radice. I nodi che sono “periferici” nella rete rispetto al nodo radice non riceveranno direttamente da questo i messaggi di sincronizzazione, ma dal nodo più vicino che si è sincronizzato (che può essere a sua volta sincronizzato con un altro nodo e non con la radice). Ne deriva che la precisione della sincronizzazione decresce all’aumentare della distanza dal nodo radice proprio perchè i nodi periferici non si sincronizzano con il valore vero del clock della radice ma con una sua stima affetta da errore. Il protocollo definisce anche come gestire l’elezione del nodo radice, come gestire messaggi di sincronizzazione da sorgenti diverse, e come gestire variazioni della topologia della rete o spegnimento della radice: • elezione della radice: dal momento che nessun nodo della rete è dedicato a funzionare da riferimento temporale, il nodo radice deve essere eletto dinamicamente. Si utilizza per questa funzione l’ID univoco che identifica ogni nodo, e si sceglie come radice il nodo con ID più basso. Il meccanismo di elezione funziona nel seguente modo: ciascun nodo che non riceve messaggi di sincronizzazione per un certo periodo di tempo inizia a mandarli lui stesso dichiarandosi nodo radice. C’è ovviamente la possibilità che più 2 In generale tutti gli algoritmi di sincronizzazione hanno una precisione migliore se il ti- mestamping viene effettuato al livello MAC, dal momento che viene rimossa la maggior parte dell’incertezza sia lato sender che lato receiver. Alcuni algoritmi, come RBS, eliminano già l’incertezza lato sender, altri, come FTSP, basano il proprio funzionamento sul fatto che i punti ideali di trasmissione e ricezione non soffrono di jitter in ricezione e trasmissione. In generale, con il timestamping al livello MAC tutti gli algoritmi migliorano di molto la precisione. 6.5 FTSP 77 nodi si dichiarino contemporaneamente root, tra questi, coloro che ricevono messaggi di sincronizzazione e vedono che il proprio ID è più alto di quello contenuto nei messaggi, smettono di inviarli e accettano l’altro nodo (quello con ID più basso) come radice. • gestire informazioni ridondanti: il globaltime può giungere a un nodo attraverso differenti percorsi, dunque arrivare in ritardo o comunque con precisione deteriorata dato che è il risultato di passaggi su più hop. Dunque ciascun nodo deve selezionare attentamente quali dei valori ricevuti deve inserire nel subset di dati usati per la regressione; ogni nodo radice mantiene un sequenceNumber che incrementa ogni volta che manda un messaggio di sincronizzazione, e il nodo ricevente tiene traccia del più grande sequenceNumber finora ricevuto e scarta i paccchetti più vecchi (con sequenceNumber minore). • spegnimento della radice: nelle sensor network lo spegnimento di un nodo per esaurimento della batteria è un avvenimento molto frequente, quindi l’algoritmo deve gestire l’eventualità di spegnimento del nodo radice. In questo caso l’elezione di un nuovo nodo radice viene effettuata con un meccanismo simile a quello della prima elezione; tutti i nodi che si dichiarano root però non trasmettono il loro tempo locale, ma la stima del tempo globale che effettuano con gli ultimi dati disponibili. Come conseguenza, se nel caso della prima elezione il nodo radice ha skew nullo e il suo localtime coincide con il globaltime della rete, nel caso di una radice che subentra ad un’altra, essa ha skew diverso da zero rispetto al globaltime, anche se questo rimane costante a partire dall’istante in cui tale nodo diventa radice. • variazioni della topologia: i nodi possono liberamente disconnettersi e connettersi alla rete, con l’unica limitazione che la rete stessa rimanga ad ogni istante connessa. L’unico problema che non abbiamo affrontato è che un nuovo nodo che si connette alla rete abbia ID più basso di quello della radice: se cominciasse subito a trasmette il suo timestamp tutti i nodi dovrebbero accettarlo come radice e la rete andrebbe fuori sincronia. Per evitare ciò, i nodi che si connettono ad una rete attendono un certo periodo di tempo prima di trasmettere, in particolare aspettano di ricevere un numero sufficiente di messaggi di sincronizzazione per popolare la regression table e ottenere dunque una stima del globaltime (cioè sincronizzarsi con 78 Algoritmi di sincronizzazione la rete), dopodichè cominciano anch’essi, come ogni nodo sincronizzato, a trasmettere i loro timestamp. 6.5.3 Prestazioni Il test dell’algoritmo è stato effettuato su motes mica2, dapprima misurando l’errore di sincronizzazione su una coppia di nodi, e successivamente provando a sincronizzare una griglia 8x8. Nel primo caso l’errore medio è di 1, 48µs, massimo di 6, 48µs per un esperimento di 18 ore, 2, 24µs e 8, 64µs per un esperimento di 8 ore [24]. Figura 6.3: Topologia della griglia 8x8 su cui è stato testato FTSP, con l’indicazione del nodo radice ID1 . Nel secondo caso, dunque su una rete 7-hop, la precisione raggiunta è stata in media 2, 5µs, con un valore massimo dell’errore di 7, 5µs. Durante l’esperimento si è spento per due volte il nodo radice, e alternativamente metà dei nodi (ricreando dunque la situazione di dover ri-eleggere il nodo radice e di dover ri-sincronizzare metà dei nodi, che si presentavano come nuovi nodi): l’errore medio è comunque rimasto sugli 11, 7µs (per 7 hop, che risulta in 1, 7µs per hop), con un valore massimo di 38µs. Tutti questi valori si riferiscono al clock a 7,37 Mhz. La precisione ottenuta sui tmote sky è di 19, 84µs3 su una piccola rete di 3 Importante notare che si tratta di valori medi: infatti l’oscillatore al quarzo a 32khz ha una risoluzione di 30, 5µs. 6.6 Average Timesync 79 quattro nodi e di 36, 75µs sulla griglia 8x8. Questi valori sono ottenuti usando il clock a 32khz fornito dall’oscillatore esterno al quarzo. La precisione ottenuta con il clock a 1Mhz fornito dal DCO è di 35, 56µs sulla rete di quattro nodi e di 155, 52µs sulla griglia 8x8. Questi valori sono stati ottenuti con un TimeSync Rate di 30 secondi, aumentando tale parametro a 2 secondi otteniamo precisioni molto maggiori, 7, 89µs con il clock a 32khz e 12, 72µs con il clock a 1Mhz. 6.6 Average Timesync Il nuovo algoritmo che proponiamo in questo lavoro si basa su due intuizioni: • che l’utilizzo di un valore concordato in maniera distribuita dei parametri di skew e offset possa aumentare la robustezza della rete, eliminando la dipendenza della sincronizzazione dal nodo radice. • che eliminando la necessità, una volta che il nodo radice sia spento, di ripetere il processo di elezione della radice — operazione che comporta un notevole dispendio in termini energetici per la trasmissione dei pacchetti necessari — si riduca il consumo energetico e allunghi la vita della rete. 6.6.1 Modello Abbiamo considerato il modello del clock presentato nel capitolo 3.1, cioè ( ẋi = 1 xi0 (frequenza di avanzamento fissa) = offset (valore del clock 6= 0 all’istante iniziale) (6.2) modello che discretizzo nel seguente modo: ( xik+1 = xik + d xi0 = offset (6.3) in realtà d = dik = d¯i + dvk , con dvk ∼ N (0, σa ), cioè l’intervallo di cui aumenta il clock tra un tick e l’altro dipende dal nodo Ni e dall’istante k ed è formato da una componente media e da una istantanea, quest’ultima processo aleatorio gaussiano a media nulla. Anche le misurazioni che ciascun nodo ottiene del clock degli altri nodi sono affette da errore che supponiamo anch’esso gaussiano, cioè yki = xik = xjk + vk , dove vk ∼ N (0, σv ) (se ho una stima del tempo di trasmissione di un messaggio 80 Algoritmi di sincronizzazione da un nodo ad un altro, posso considerare il processo aleatorio vk a media uguale a tale stima). Cerchiamo di dare delle formule per l’aggiornamento del tempo virtuale, cioè il clock globale a cui si sincronizzano tutti i nodi della rete: d¯ medio }| { z 1 X¯ tv tv di x = xk + k+1 N xtv 0 (6.4) 1 X i = x0 |N {z } x0 medio dove abbiamo indicato per semplicità d¯ medio e x0 medio come media di N campioni, anche se nell’implementazione i campioni possono essere pesati diversamente. In particolare, i campioni più recenti avranno peso maggiore in quanto si suppone siano già essi prodotto di altre medie e dunque più vicini al valore vero dal clock virtuale. Uno dei problemi da risolvere sarà determinare come vengono pesati i vari campioni che costituiscono le media in modo da minimizzare xi − xtv , ovvero k k determinare il valore di ρ in modo che la formula per l’aggiornamento della media, cioè dˆk+1 = (1 − ρ) · dˆk + ρ · djk dove dˆk è la media corrente e djk un valore da inserire nella media 4 , abbia la proprietà di minimizzare l’errore. 6.6.2 Algoritmo Nella prima fase, subito successiva all’accensione della rete, ciascun nodo manda un pacchetto di sincronizzazione contenente il suo ID e una lettura del suo clock locale, dopodichè si mette in attesa per ricevere un pacchetto di questo tipo: il primo pacchetto che riceve stabilisce quale sarà il suo partnerNode, cioè il nodo che userà per una prima stima dello skew. Ciascun nodo dunque ha un nodo partner che usa per stabilire un valore per lo skew e uno per l’offset. Dopodichè incomincia a mandare pacchetti di sincronizzazione contenenti il suo timestamp, il suo offset e il suo skew rispetto al virtual 4 I k a pedice non si riferiscono ad istanti temporali sulla scala del tempo globale della rete, ma servono semplicemente a definire quali valori di dˆ sono più “nuovi” di altri. 6.7 Esperimenti effettuati 81 time (che all’inizio identifica come il tempo del partner node): il primo valore viene usato dal partner node per aggiornare la stima di skew e offset, i secondi vengono usati dagli altri nodi per aggiornare le medie che determinano il virtual time. Mentre il valore dello skew viene semplicemente mediato (con pesi maggiori per i valori più nuovi), il valore dell’offset, che deve essere aggiornato ogni volta che si aggiungono valori nuovi alla regression table, viene mantenuto, ovvero per ciascun nodo viene semplicemente aggiunto all’offset precedente il tempo trascorso. Dunque ogni volta che vengono ricalcolati α e β al virtual offset precedente viene semplicemente sommato l’intervallo di tempo trascorso da quando era stata calcolata predentemente la stima. 6.7 Esperimenti effettuati Nell’effettuare il porting dell’algoritmo FTSP sui motes a disposizione, i moteiv tmote sky, si è reso necessario trovare un modo per fornire timestamp a 32 bit del valore del clock locale. Dal momento che il microcontrollore che equipaggia i motes, il Texas Instruments MSP430, è un processore a 16 bit, si hanno a disposizione solamente contatori a 16 bit: se usati per contare i ticks dell’oscillatore al quarzo esterno, che va a 32Khz, vanno in overflow ogni 2 secondi, se usati per contare i ticks dell’oscillatore interno (DCO), che noi abbiamo usato alla frequenza di 1Mhz, vanno in overflow ogni 0,06 secondi. È stato necessario dunque gestire via software questi overflow, incrementando un contatore a 32 bit di 217 ogni volta che il microcontrollore segnalava con una interruzione un overflow del contatore a 16 bit. Una volta ottenuto un clock a 32 bit, abbiamo verificato che le caratteristiche dello skew di questi oscillatori fossero compatibili con l’ipotesi di linearità che abbiamo fatto scegliendo di approssimare, nella regressione lineare, l’andamento dei campioni del clock del nodo radice con un polinomio di primo grado. 6.7.1 Accuratezza dell’oscillatore al quarzo Abbiamo dimostrato che l’oscillatore al quarzo è una sorgente di clock stabile sul lungo periodo, ma poco accurata sul breve periodo. Per verificare ciò abbiamo programmato un nodo per spedire, ad intervalli regolari di 521 millisecondi, pac- 82 Algoritmi di sincronizzazione chetti attraverso la porta seriale ad un PC, e misurato tramite il clock del PC gli intervalli tra l’istante di ricezione di un pacchetto e il successivo. Notiamo che questi intervalli, misurati tramite il clock del PC, non sono sempre uguali, ma oscillano su una piccola fascia di valori: questo significa che il clock dell’oscillatore non è preciso sul breve periodo (la durata dei singoli cicli di clock è variabile), ma sul lungo periodo è accurato, dal momento che la fascia in cui oscillano i valori è piccola e limitata anche dopo un lungo periodo (30 minuti, nell’esperimento). Figura 6.4: Durata degli intervalli tra la spedizione di un messaggio e il successivo (512 millisecondi) misurati secondo il clock del mote (32khz, rosso) e quello del pc (blu). 6.7.2 Deriva dei clock a 32Khz Per misurare la deriva degli oscillatori abbiamo usato un apparato sperimentale composto da cinque nodi moteiv tmote sky. Uno di questi spedisce a intervalli temporali di 1 secondo pacchetti contenenti il proprio timestamp agli altri quattro, i quali memorizzano il corrispondente timestamp di ricezione. I timestamp vengono presi al livello MAC all’istante di trasmissione e di ricezione, utilizzando la caratteristica del chip radio CC2420 di segnalare un’interruzione quando il canale si libera (trasmissione) e quando viene ricevuto il primo byte del pacchetto (ricezione): quando il programma riceve questa interruzione legge il valore del clock locale. Abbiamo ottenuto quindi una serie di timestamp che ci mostrano l’andamento dell’offset dei clock di ciascun nodo rispetto al primo. Vediamo in Figura 6.5 che l’offset dopo trenta minuti è nell’ordine dei 600 ticks, che con un clock a 32khz significa 0,018 secondi; l’oscillatore esterno al quarzo mostra dunque un’alta 6.7 Esperimenti effettuati 83 stabilità sul lungo periodo, anche se l’accuratezza (come si vede nel paragrafo 6.7.1) non è delle migliori. Abbiamo dimostrato comunque che questo tipo di sorgente di clock è adatta ai nostri scopi: dato che mostra uno skew costante sul lungo periodo, e che quindi il valore futuro del clock è predicibile con buona precisione, il nodo può rimanere per un lungo periodo senza ricevere o spedire messaggi di sincronizzazione, ottimizzando il consumo energetico. 6.7.3 Deriva dei clock a 1Mhz (DCO) Lo stesso apparato sperimentale del paragrafo 6.7.2 è stato usato per questo esperimento, con l’unica differenza che in questo caso la sorgente di clock era il Digital Controlled Oscillator (DCO) interno al microcontrollore, funzionante alla frequenza di 1Mhz. Notiamo dai grafici in Figura 6.6 che gli offset non seguono un andamento di una qualche regolarità. Con una analisi più approfondita abbiamo attribuito la colpa di questo andamento irregolare al modulo di calibrazione continua, dichiarato in MSP430DCOCalibC.nc e implementato in MSP430DCOCalibM.nc. Questo modulo serve a sincronizzare, ad ogni overflow del contatore a 16 bit ACLK del MSP430 — che normalmente conta i ticks dell’oscillatore al quarzo a 32khz — il contatore MCLK che conta i ticks del DCO; questo significa che se all’istante in cui ACLK va in overflow il contatore MCLK ha contato ticks in più o in meno rispetto a quanto atteso (in realtà in più o in meno rispetto ad una soglia di tolleranza di 7 ticks), questi vengono rispettivamente sottratti o aggiunti al contatore stesso in modo da “contenere” la deriva del DCO, che come vedremo in seguito è molto veloce. L’enorme variabilità nel comportamento del DCO causata da questo modulo è data dal fatto che il DCO stesso si spegne quando la MCU (Master Control Unit) del microcontrollore va in sleep mode, per cui misurare intervalli di tempo tra due successivi interrupt produce risultati senza significato, dal momento che il contatore, all’interrupt che lo riaccende, riparte da dove si era fermato a contare al momento dello spegnimento. In dettaglio: • La calibrazione confronta il numero di ticks del clock SMCLK (il DCO) con il valore del clock fornito dall’oscillatore a 32khz (dato da TimerB); 84 Algoritmi di sincronizzazione Figura 6.5: Sopra: andamento degli offset (in verde) nel tempo tra quattro nodi e un nodo di riferimento, usando come sorgente del clock l’oscillatore al quarzo a 32khz. Sotto: Ingrandimento della zona indicata nel quadrato: notiamo che sebbene molto stabili sul lungo periodo, le misurazioni non sono accurate sul breve periodo (il loro andamento non è perfettamente rettilineo). 6.7 Esperimenti effettuati 85 Figura 6.6: Andamento degli offset nel tempo tra quattro nodi e un nodo di riferimento, usando come sorgente del clock il DCO interno a 1Mhz. Vediamo che a lungo termine gli offset variano in maniera casuale, a causa dell’intervento della routine di calibrazione continua. 86 Algoritmi di sincronizzazione • In TinyOS l’oscillatore a 32khz è sempre in funzione, a differenza del DCO; • Il DCO si ferma quando la MCU entra in modalità a basso consumo (LMP3); • Lo scheduler di TinyOS manda la MCU in modalità a basso consumo (low power mode, LPM3) quando non ci sono interrupt pendenti o task da eseguire (la coda dei task è vuota): questo avviene molto spesso perchè tipicamente i task non sono computazionalmente pesanti e quindi terminano in breve tempo. Dunque, anche se la routine di calibrazione forza TinyOS a non entrare nella modalità LPM3, nella realtà questo avviene spesso. Ciò significa che misurare intervalli di tempo tra interrupt (sia su SMCLK che ACLK) non dà risultati accurati. Ecco perchè al routine MSP430DCOCalibM, che tenta di calibrare il DCO, in realtà non funziona affatto. In Figura 6.7 vediamo un plottaggio dei valori degli offset del clock del DCO disattivando la routine di calibrazione continua prima citata: notiamo che la stabilità sul lungo periodo è molto bassa (dopo 30 minuti l’offset è nell’ordine della trentina di secondi), ma per i nostri scopi l’importante è dimostrare che sul lungo periodo l’andamento è lineare (o quasi, dal momento che l’andamento degli offset, dopo una fase di stabilizzazione iniziale, è rettilineo) 6.7.4 FTSP 32Khz Descrizione dell’esperimento Abbiamo testato l’algoritmo su un quadrato di quattro nodi e su una griglia composta da 64 nodi disposti su un quadrato 8x8 (vedi Figura 6.3); ciascun nodo poteva trasmettere alla massima frequenza, ma la topologia è stata forzata via software in modo che ciascun nodo elaborasse solo i pacchetti che provenivano dai suoi vicini (orizzontali, verticali e diagonali), scartando gli altri, in modo da verificare le prestazioni dell’algoritmo in una rete multihop. Per rendere l’operazione di più semplice implementazione, l’ID di ciascun nodo è composto da 16 bit cosı̀ suddivisi: Il nodo radice, cioè quello con ID più basso, si trova al centro della griglia, in posizione (4,4) e sarà identificato come ID1 . I nodi sono stati accesi contemporaneamente, e l’algoritmo è stato lasciato girare per 20 minuti nel caso del quadrato di quattro nodi, e per un’ora nel caso della griglia 8x8. 6.7 Esperimenti effettuati 87 Figura 6.7: Andamento degli offset nel tempo tra quattro nodi e un nodo di riferimento, usando come sorgente del clock il DCO interno a 1Mhz. Vediamo che disattivando la routine di calibrazione continua il clock del DCO mostra una pessima stabilità sul lungo periodo (dopo 30 minuti l’offset è nell’ordine della trentina di secondi), ma per i nostri scopi l’importante è che l’andamento sia lineare (skew costante o quasi). 88 Algoritmi di sincronizzazione 4 bit 0x 4 bit gruppo 4 bit 4 bit riga colonna Modalità di calcolo Per ogni esperimento sono plottate rispetto al tempo la percentuale di nodi sincronizzati della rete (cioè nodi che, avendo almeno 4 elementi nella regression table, riescono ad effettuare una stima di skew e offset relativo del proprio clock rispetto al clock del nodo radice) e l’errore medio. Quest’ultimo valore è calcolato determinando il valore medio dei clock di tutti i nodi ogni 30 secondi (polling period ) e calcolando la differenza tra questo valore medio e il valore del clock di ciascun nodo durante lo stesso polling period. Risultati Analizziamo i risultati, riportati in Figura 6.8, dell’esperimento sulla piccola rete composta da quattro nodi. L’errore medio (in blu) si mantiene limitato sotto i 20µs: è importante notare che questo risultato è possibile proprio perchè si calcola il valore medio, dal momento che la granularità del clock è di 30, 5µs, dunque superiore al valore prima citato. La percentuale di nodi sincronizzati cresce velocemente allo startup della rete e si attesta sul 100%: un nodo sincronizzato infatti rimane in tale stato a meno che non riceva per un lungo periodo di tempo nuovi pacchetti di sincronizzazione, e dunque non riesca ad aggiornare la stima dei parametri del clock remoto: in tal caso è costretto ad eliminare, uno ad uno, i campioni che ha già nella regression table man mano che “invecchiano” (cioè differiscono dal valore corrente del clock di una quantità superiore ad una soglia predefinita, parametro dell’algoritmo, chiamata ENTRY_THROWOUT_LIMIT). Questo può accadere in seguito a problemi di trasmissione, dovuti anche ad elevato traffico, e se il nodo applica meccanismi di risparmio energetico basati sullo spegnimento del chip radio per lunghi periodi di tempo. I risultati dell’esperimento sulla griglia sono riportati in Figura 6.9. In tal caso l’errore medio è più alto a causa della configurazione della rete che prevede che ciascun nodo riceva solo i pacchetti dei suoi vicini: simulare in questo modo il multihop non elimina la congestione della rete dovuta alla presenza di molti nodi, dal momento che nel multihop reale nodi ai capi della rete possono trasmettere insieme senza disturbarsi, mentre nel nostro caso molti nodi, trovando il canale 6.7 Esperimenti effettuati 89 occupato, non riescono a trasmettere i propri messaggi di sincronizzazione. Il fatto che molti nodi per questo motivo “saltino” alcuni round di sincronizzazione fa si che l’errore medio sia più elevato. Riassumiamo nella tabella 6.1 i risultati numerici ottenuti negli esperimenti con FTSP e il clock a 32khz: Configurazione Timesync Errore Errore rete period medio massimo Quadrato 4 motes 30 sec 19, 83µs 24, 16µs Griglia 8x8 30 sec 36, 75µs 73, 46µs Quadrato 4 motes 2 sec 7, 89µs 9, 25µs Tabella 6.1: Riassunto dei risultati numerici medi ottenuti da FTSP con il clock a 32khz. Figura 6.8: La figura riporta i risultati dell’esperimento con FTSP (sorgente del clock: oscillatore al quarzo a 32khz) su una piccola rete di quattro nodi: percentuale dei nodi sincronizzata (in rosso), errore medio (in blu) ed errore massimo (in verde): i picchi di errore si verificano in occasione di basse percentuali di nodi sincronizzati. 6.7.5 FTSP 1Mhz La struttura dell’esperimento è la stessa descritta in 6.7.4, solo che in questo caso la sorgente del clock nei motes non è l’oscillatore al quarzo esterno a 32khz bensı̀ il DCO interno a 1Mhz. 90 Algoritmi di sincronizzazione Figura 6.9: La figura riporta i risultati dell’esperimento con FTSP (sorgente del clock: oscillatore al quarzo a 32khz) sulla griglia 8x8: percentuale dei nodi sincronizzata (in rosso), errore medio (in blu) ed errore massimo (in verde). Risultati Analizziamo i risultati riportati in Figura 6.10 e 6.11. Valgono tutte le considerazioni effettuate nel paragrafo precedente per gli stessi esperimenti con il clock a 32khz; sebbene ci si possa aspettare un miglioramento delle prestazioni, in realtà otteniamo errori più alti a causa del particolare hardware con cui ci troviamo ad operare. Il DCO è infatti una sorgente di clock molto più instabile dell’oscillatore al quarzo e dunque in un polling period l’errore accumulato dal clock è più elevato. In altre piattaforme, ad esempio mica2, questa instabilità è compensata da una calibrazione continua del DCO, che non è stata applicata in questi esperimenti a causa degli errori nella routine di calibrazione continua spiegati dettagliatamente nel Paragrafo 6.7.3 e nell’appendice A.3. Riassumiamo nella tabella 6.2 i risultati numerici ottenuti negli esperimenti con FTSP e il clock a 1Mhz. Abbiamo aggiunto, rispetto ai test precedenti, il parametro ENTRY_THROWOUT_LIMIT, che indica la soglia oltre la quale un campione deve essere considerato “vecchio” e quindi rimosso dalla regression table: notiamo che all’aumentare della soglia le stime peggiorano perchè effettuate con campioni molto distanti nel tempo, e dunque meno correlati tra loro di quanto lo potrebbero essere campioni vicini nel tempo. Questa osservazione è importante, dal momento che l’ipotesi che l’approssimazione ai minimi quadrati di una serie di campioni dia informazioni valide sull’andamento del segnale è basata sul fatto che questi campioni siano correlati tra di loro: distanziandoli nel tempo, se il segnale è fortemente tempovariante questa ipotesi cade, e le stime risultano imprecise. 6.7 Esperimenti effettuati 91 Figura 6.10: La figura riporta i risultati dell’esperimento con FTSP (sorgente del clock: DCO a 1Mhz) su una piccola rete di quattro nodi: percentuale dei nodi sincronizzata (in rosso), errore medio (in blu) ed errore massimo (in verde). Figura 6.11: La figura riporta i risultati dell’esperimento con FTSP (sorgente del clock: DCO a 1 Mhz) sulla griglia 8x8: percentuale dei nodi sincronizzata (in rosso), errore medio (in blu) ed errore massimo (in verde). Configurazione Timesync Errore Errore ENTRY_THROWOUT rete period medio massimo limit Quadrato 4 motes 10 sec 35, 56µs 44, 18µs 800 Quadrato 4 motes 10 sec 132, 21µs 219, 7µs 8388606 Quadrato 4 motes 2 sec 12, 72µs 12, 72µs 800 Griglia 8x8 10 sec 155, 52µs 379, 77µs 800 Tabella 6.2: Riassunto dei risultati numerici medi ottenuti da FTSP con il clock a 1Mhz. 92 Algoritmi di sincronizzazione 6.7.6 Average 32Khz Non avendo ancora completato l’implementazione dell’algoritmo sui motes a nostra disposizione, abbiamo dapprima testato la validità della nostra intuizione, ovvero che il calcolo distribuito del valore di offset sul lungo periodo converge ad un valore comune. Nei nostri testabbiamo verificato l’effettiva convergenza con il metodo di calcolo da noi implementato. Notiamo che l’errore medio è comunque alto, nell’ordine dei 300µs, paragonabile dunque a quello che si otterrebbe lasciando il clock dei nodi libero di derivare: ciò non deve spaventare, dal momento che la precisione si ottiene tramite la determinazione dei valori di skew e il loro successivo utilizzo per compensare la deriva degli oscillatori durante l’intervallo di sincronizzazione. 6.8 Conclusioni In conclusione, abbiamo verificato che delle due sorgenti di clock presenti sul moteiv tmote sky, l’oscillatore al quarzo a 32khz e il DCO, la prima è molto stabile sul lungo periodo ma con una risoluzione bassa (1 tick = 30, 5µs), la seconda ha una risoluzione più alta ma una bassissima stabilità, resa ancor peggiore dall’assenza – al momento in cui si scrive – di un modulo funzionante di calibrazione continua del DCO con l’oscillatore al quarzo. Il porting di FTSP su questa piattaforma ha rivelato quanto ci aspettavamo, e cioè che sono ottenibili buone precisioni con l’oscillatore a 32khz, limitatamente alla risoluzione dello stesso, e che il clock del DCO è inutilizzabile se non calibrato per via della sua bassissima stabilità. Le precisioni ottenute sono comparabili con quelle presenti in letteratura [24], ottenute con clock a frequenze più elevate. È possibile “dimensionare” l’errore medio della sincronizzazione agendo su vari parametri, dei quali i fondamentali sono l’intervallo di campionamento (Timesync Rate), che indica ogni quanto devo prendere i campioni poi usati per la stima dell’andamento del clock, e la Soglia di throuwout (ENTRY_THROWOUT_LIMIT), che indica l’età dei campioni usati per la stima stessa: al diminuire del Timesync Rate aumenta la precisione, cosı̀ come al diminuire della soglia, perchè vengono usati per la stima campioni più recenti. Abbiamo proposto un nuovo algoritmo, Average Timesync, che determina i parametri di offset e skew come valore medio tra tutti i nodi della rete calcolato secondo un meccanismo di Average Consensus, e abbiamo verificato sperimentalmente la convergenza dell’algoritmo limitatamente al solo offset. 6.9 Sviluppi futuri 6.9 93 Sviluppi futuri Abbiamo dimostrato che è possibile fornire un servizio di sincronizzazione, su una rete di motes moteiv tmote sky, che metta a disposizione una scala temporale globale. A differenza di molte metodologie post-facto, per cui si effetta la sincronizzazione e la conversione del timestamp durante la trasmissione delle misure alla base station, i sistemi presentati forniscono l’informazione temporale istantaneamente; la contropartita è la necessità di mantenere la sincronizzazione tra i nodi, tramte lo scambio periodico di messaggi di sincronizzazione. È più che mai necessaria una implementazione del servizio di sincronizzazione che sia indipendente dalla piattaforma su cui viene eseguita, e ciò si può ottenere solamente con una nuova progettazione del sistema operativo TinyOS per quanto riguarda la parte del contatori e dei Timer: il servizio di sincronizzazione deve sapere che una tal libreria fornirà esso un clock con le caratteristiche di stabilità e skew di cui ha bisogno su tutte le piattaforme, mentre al momento in cui si scrive tali funzioni sono fornite da librerie diverse a seconda della piattaforma. Il team che si occupa della progettazione della versione 2.0 di TinyOS sembra concordare su questa necessità, visto il lavoro preliminare che è stato fatto per la definizione della nuova interfaccia Timer. Rimandiamo per un ulteriore approfondimento al documento TEP102 riportato in appendice B. Per ottimizzare ulteriormente le prestazioni si potrebbe utilizzare il lavoro del capitolo 5.2 per calcolare a runtime il tempo massimo per il quale un nodo può restare senza ricevere informazioni di sincronizzazione e comunque fornire una stima del global time affetta da un errore accettabile. 94 Algoritmi di sincronizzazione Appendice A Calibrazione Volete aver molti in aiuto? Cercate di non averne bisogno. Alessandro Manzoni La calibrazione è il problema di mappare l’output di un sensore su una scala ben definita. La sincronizzazione temporale può dunque essere vista come una particolare forma di calibrazione. Anche nella calibrazione di cui si parla in 6.7.3 si tenta di mappare l’output del clock del DCO (alcuni valori di questo output, presi a intervalli regolari) su una scala temporale data dal clock dell’oscillatore al quarzo. In questa appendice tratteremo più genericamente del problema della calibrazione — e della calibrazione di quei particolari sensori che sono gli orologi — in una sensor network. A.1 La sincronizzazione è una calibrazione I sensori sono dispositivi hardware che hanno in input e un output. L’input è una certa quantità fisica, come temperatura, luce, accelerazione, ecc, l’output è tipicamente un segnale elettrico come una tensione o una corrente. Un convertitore analogico-digitale converte poi tale segnale in un numero. Un clock hardware è solitamente composto di quattro parti: un apparato fisico con un comportamento periodico (un pendolo, un oscillatore al quarzo, un atomo di cesio,...), un sensore che converte il fenomeno fisico in un segnale elettrico, un ADC che converte il segnale in un bit (ad esempio un rivelatore di soglia), e un contatore che conta questi valori. Un clock contiene dunque, tra le altre cose, un sensore e il fenomeno fisico che questo sensore misura. 96 Calibrazione Il tempo come quantità fisica ha comunque delle caratteristiche che lo diffe- renziano dalle altre quantità fisiche che solitamente si misurano. Per esempio, in molte applicazioni reali, le quantità osservate si trovano in un intervallo di valori (la temperatura ad esempio ∈ [-30◦ C,+30◦ C]): l’errore di misura, dato dall’errore del sensore, è anch’esso limitato. Il tempo invece è una quantità che cresce indefinitamente, per cui l’errore di un clock sofware cresce anch’esso indefinitamente. Sono dunque necessari meccanismi per compensare per le derive dei clock e sincronizzazioni ripetute periodicamente. A.2 La calibrazione nelle sensor network La calibrazione è un problema che si pone sempre per qualsiasi strumento di misura. A dispetto di questo però, nelle sensor network il problema non è stato approfondito, almeno non quanto lo è stata la sincronizzazione. Un gran numero di sensori, di cui sono tipicamente composte le sensor network, non può essere calibrato manualmente uno per uno. Questo è ancora più vero per le calibrazioni a coppie, nelle quali ciascun sensore deve essere calibrato con ciascun altro. Ad esempio, nelle installazioni utilizzate per il posizionamento mediante la misura dell’intensità del segnale radio ricevuto, ciascun nodo deve misurare il segnale radio ricevuto da ciascun altro, il che ci porta ad un numero quadratico di operazioni di calibrazione. Un esempio di questa calibrazione è l’applicazione Motetrack di Matt Welsh, che richiede una calibrazione iniziale con la rete di sensori usata, per stabilire una tabella di campioni poi usati per determinare la posizione di un nodo mobile per similarità nelle potenze del segnale ricevuto: la tabella creata in questo caso viene distribuita compilata nel codice dell’applicazione, ma sarebbe molto più efficace se essa venisse calcolata senza la necessità di un nodo mobile per prendere i campioni. Se ciascun nodo della rete fissa misurasse la potenza del segnale che riceve da ciascun altro nodo, la tabella cosı̀ ottenuta potrebbe essere distribuita via wireless con la rete in funzione, eliminando la necessità di nuova calibrazione e riprogrammazione dei nodi ogni volta che vi sono mutamenti nella situazione ambientale tali che le misure di riferimento in possesso dei nodi non sono pià valide. A.3 Calibrazione continua del DCO A.3 97 Calibrazione continua del DCO Un altro problema di calibrazione in cui ci siamo imbattuti durante il nostro lavoro è stato quello della calibrazione effettuata sul DCO dei motes moteiv tmote sky in nostro possesso, per limitare la sua bassa stabilità sul lungo periodo. Il meccanismo iniziale prevedeva che ad ogni overflow del contatore TimerB, collegato alla sorgente di clock ACLK (oscillatore al quarzo a 32khz) venisse letto anche il contatore di TimerA, che invece ha come sorgente di clock il DCO. Se il DCO avanza ad 1Mhz, per esempio, ad ogni overflow di TimerB il valore di TimerA dovrebbe essere aumentato di ∆ = 2 · 1024 · 1024 ticks, se è aumentato di un valore inferiore o superiore, allora il DCO ha bisogno di essere ricalibrato. Entrando nel dettaglio, è prevista una soglia di tolleranza entro la quale si preferisce non ricalibrare il DCO (operazione che consuma risorse e richiede tempo). Se la differenza [(valoreAttuale − ∆) − (valoreP recedente)] è maggiore di zero, allora il DCO sta andando troppo veloce e deve essere “rallentato”: però la frequenza viene aggiustata solo se tale differenza è maggiore della soglia. Allo stesso modo, se la differenza [(valoreAttuale − ∆) − (valoreP recedente)] è minore di zero, il DCO sta andando troppo piano e deve essere velocizzato, ma la correzione viene applicata solo se la differenza è minore del valore negativo della soglia. Riportiamo, per comodità, la prima versione del codice di calibrazione continua, contenuta in MSP430DCOCalibM.nc versione 1.1, nella directory \$TOSROOT\tos \platform \msp430: module MSP430DCOCalibM { uses interface LocalTime as LocalTimeMicro; uses interface MSP430Timer as Timer32khz; } implementation { uint32 t m prev; enum { TARGET DELTA = 2L∗1024L∗1024L, // 2 seconds of a binary 1MHz ←clock MAX DEVIATION FRACTION = 571, // (1/(.35%/2)), .35% is about ←the change of one calib tick 98 Calibrazione MAX DEVIATION = (TARGET DELTA / ←MAX DEVIATION FRACTION), }; async event void Timer32khz.overflow() { uint32 t now = call LocalTimeMicro.read(); uint32 t now32khz = call Timer32khz.read(); int32 t dev; // roughly adjust for any latency in servicing this interrupt now = now − (now32khz << 5); dev = (now − m prev) − TARGET DELTA; m prev = now; if( (dev < −MAX DEVIATION) || (dev > MAX DEVIATION) ) { uint16 t calib = ((BCSCTL1 & 7) << 8) | DCOCTL; if( dev > MAX DEVIATION ) { // running too fast, slow down the DCO if( calib > 0 ) { calib−−; // if we’re left the current RSELx, jump down into the middle of the ←one below if( (calib & 0x0e0) == 0x0e0 ) calib −= (3 << 5); } } else { // running too slow, speed up the DCO if( calib < 0x7e0 ) // DCO calib can’t go higher than 0x7e0 { calib++; // if we’re leaving this RSELx, jump up into the middle of the one ←above if( (calib & 0x0e1) == 0x0e1 ) calib += (3 << 5); } } BCSCTL1 = (BCSCTL1 & ˜0x07) | ((calib >> 8) & 0x07); DCOCTL = calib & 0xff; A.3 Calibrazione continua del DCO 99 } } } Listato A.1: Routine di calibrazione continua del DCO, versione 1.1 (sugli overflow del clock a 32khz). Successivamente si è pensato di rendere più frequente la calibrazione, agendo ad ogni overflow del contatore che aveva come sorgente di clock lo stesso DCO, cioè ad ogni oveflow di TimerA veniva letto anche TimerB. Sempre nel caso del DCO a 1Mhz, ad ogni overflow del TimerA il contatore dell’oscillatore al quarzo dovrebbe essere avanzato di 2048 ticks: il controllo sulla differenza viene fatto allo stesso modo, e cosı̀ il cambio della frequenza operativa del DCO, cioè agendo sui registri del microncontrollore DCOCTL e BCSCTL1. Riportiamo da [3] la tabella che mette in relazione i valori di DCOCTL e BCSCTL1 con la frequenza operativa del DCO, e, come nel caso precedente, il codice dell’implementazione della routine di calibrazione, contenuta in MSP430DCOCalibM.nc versione 1.2, nella directory \$TOSROOT\tos \platform \msp430: Figura A.1: Valori di frequenza del DCO per varie combinazioni dei bit DCOx e RSELx. module MSP430DCOCalibM { uses interface MSP430Timer as TimerMicro; uses interface MSP430Timer as Timer32khz; } implementation { uint16 t m prev; 100 Calibrazione enum { TARGET DELTA = 2048, // number of 32khz ticks during 65536 ticks ←at 1mhz MAX DEVIATION = 7, // about 0.35% error }; // this gets executed 32 times a second async event void TimerMicro.overflow() { uint16 t now = call Timer32khz.read(); uint16 t delta = now − m prev; m prev = now; if( delta > (TARGET DELTA+MAX DEVIATION) ) { // too many 32khz ticks means the DCO is running too slow, speed it ←up if( DCOCTL < 0xe0 ) { DCOCTL++; } else if( (BCSCTL1 & 7) < 7 ) { BCSCTL1++; DCOCTL = 96; } } else if( delta < (TARGET DELTA−MAX DEVIATION) ) { // too few 32khz ticks means the DCO is running too fast, slow it ←down if( DCOCTL > 0 ) { DCOCTL−−; } else if( (BCSCTL1 & 7) > 0 ) { BCSCTL1−−; DCOCTL = 128; } } } async event void Timer32khz.overflow() A.3 Calibrazione continua del DCO 101 { } } Listato A.2: Routine di calibrazione continua del DCO, versione 1.2 (sugli overflow del clock a 1Mhz). Al momento in cui si scrive la routine di calibrazione continua non è funzionante, a causa di un malfunzionamento nella gestione delle modalità a basso consumo del MPS430 da parte di TinyOS. Nel dettaglio, il DCO si spegne quando la MCU (Master Control Unit) del microcontrollore va in sleep mode, per cui misurare intervalli di tempo tra due successivi interrupt produce risultati senza significato, dal momento che il contatore, all’interrupt che lo riaccende, riparte da dove si era fermato a contare al momento dello spegnimento (vedi Par.6.7.3). 102 Calibrazione Appendice B TEP102: Timers In protocol design, perfection has been reached not when there is nothing left to add, but when there is nothing left to take away. RFC #1925 Abbiamo richiamato nel paragrafo 6.9 che nella release 2.0 l’organizzazione delle componenti di TinyOS è stata completamente rivista, con lo scopo di rendere le applicazioni più facilmente portabili su varie piattaforme. A questo scopo in ogni sistema sono stati individuati dei sottosistemi essenziali e sempre presenti (chip radio, microcontrollore, ADC, sensori, power management,...) e sono state definite delle metodologie per astrarre la specifica implementazione, chiamate HAA (Hardware Abstraction Architecture, a sua volta suddiviso in tre livelli: HPL (Hardware Presentation Layer), lo strato più vicino all’hardware che mappa pin di IO e registri come classi nesC; HAL (Hardware Abstraction Layer), che fornisce servizi di base; e HIL (Hardware Independent Layer), che serve a fornire nomi comuni multipiattaforma alle classi che implementano delle funzionalità, fornite magari dall’HAL). Le proposte per ciascun sottosistema sono racchiuse nei cosiddetti TEP (TinyOS Enhancement Proposal). Riportiamo in questa appendice il TEP102, che si riferisce alla gestione dei Timers. 104 TEP102: Timers ============================ Timers ============================ :TEP: 102 :Group: Core Working Group :Type: Documentary :Status: Draft :TinyOS-Version: 2.x :Author: Cory Sharp, Martin Turon, David Gay :Draft-Created: 22-Sep-2004 :Draft-Version: $Revision: 1.1.2.3 $ :Draft-Modified: $Date: 2005/12/14 23:52:36 $ :Draft-Discuss: TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu> .. Note:: This memo documents a part of TinyOS for the TinyOS Community, and requests discussion and suggestions for improvements. Distribution of this memo is unlimited. This memo is in full compliance with TEP 1. Abstract ==================================================================== This TEP proposes a Timer design that supports common timing requirements both in precision and width across common hardware configurations. This TEP focuses on aligning the Timer abstraction with the three-layer Hardware Abstraction Architecture (HAA). 1. Introduction ==================================================================== Most microcontrollers offer a rich timer system, with features like: * several counters, possibly of different widths, with multiple clocking options * one or more compare registers for each counter, which can trigger interrupts, changes to output pins and changes to the counter value * capture of the time of input pin changes The interested reader can refer to Appendix A for a brief overview of the timer hardware on some current TinyOS platforms. TinyOS does not attempt to capture all this diversity in a platform-independent fashion. Instead, following the principles of the HAA[_tep2], each microcontroller should expose all this functionality via components and interfaces at the HPL and, where appropriate, HAL levels. However, two aspects of timers are sufficiently common and important that they should be made available in a well-defined way: measuring time, and triggering (possibly repeating) events at specific times. The rest of this TEP specifies: * a set of platform-independent interfaces for counting time and triggering 105 events (‘2. Interfaces‘_) * guidelines on how each microcontroller’s HAL SHOULD expose its timer hardware in terms of the above interfaces (‘3. HAL guidelines‘_) * what components a microcontroller’s timer HIL MUST implement (‘4. HIL requirements‘_) * a set of utility components whose use simplifies building the components specified by the HAL guidelines and HIL requirements (‘5. Utility components‘_) This TEP ends with appendices documenting, as an example, the mica2 timer subsystem implementation. 2. Interfaces ==================================================================== Before presenting the interfaces (2.2), we start with a general discussion of the issues of precision, width and accuracy in timer interfaces (2.1). 2.1 Precision, Width and Accuracy. -------------------------------------------------------------------Three fundamental properties of timers are *precision*, *width* and *accuracy*. Examples of precision are millisecond, a cycle of a 32kHz clock, and microseconds. All precisions are in "binary" units with respect to one second. That is, one second contains 1024 binary milliseconds, 32768 32kHz ticks, or 1048576 microseconds. This TEP emphasizes millisecond and 32kHz tick precisions while reasonably accommodating other precisions. Examples of widths are 8-bit, 16-bit, 32-bit, and 64-bit. The width for timer interfaces and components SHOULD be 32-bits. That is, for lack of a good reason, timer interfaces should expose a 32-bit interface. In a number of circumstances there are good reasons not to expose a 32-bit interface. This TEP emphasizes 32-bit widths while reasonably accommodating other widths. Accuracy reflects how closely a component conforms to the precision it claims to provide. Accuracy is affected by issues such as clock drift (much higher for internal vs crystal oscillators) and hardware limitations. As an example of hardware limitations, a mica2 clocked at 7.37MHz cannot offer an exact microsecond timer -- the closest it can come is 7.37MHz/8. Rather than introduce a plethora of precisions, we believe it is often best to pick the existing precision closest to what can be provided, along with appropriate documentation. However, the accuracy MUST remain reasonable: for instance, it would be inappropriate to claim that a millisecond timer is a 32kHz timer. This TEP parameterizes all interfaces by precision and some interfaces by width. This intentionally makes similar timer interfaces with different precision or width mutually incompatible. It also allows user code to clearly express and understand the precision and width for a given timer interface. Accuracy is not reflected in the interface type. 106 TEP102: Timers Precision is expressed as an empty type -- TMilli, T32khz, and TMicro -- written in the standard Timer.h header like this:: typedef struct { } TMilli; typedef struct { } T32khz; typedef struct { } TMicro; Note that the precision names are expressed as either frequency or period, whichever is convenient. 2.2 Timer interfaces -------------------------------------------------------------------This TEP proposes these timer interfaces:: interface interface interface interface interface Counter< precision_tag, size_type > Alarm< precision_tag, size_type > BusyWait< precision_tag, size_type > LocalTime< precision_tag > Timer< precision_tag > The LocalTime and Timer interfaces are used primarily by user applications and use a fixed width of 32-bits. The Alarm, BusyWait, and Counter interfaces are used by the TinyOS timer system and advanced user components. Counter -------------------------------------------------------------------A Counter component will increase the width of a low-level hardware timer by wrapping the overflow event and incrementing its higher order bits. These higher order bits are considered extra state over the HPL register layer, and therefore qualify all Counters as HAL components. The Counter interface returns the current time and provides commands and an event for managing overflow conditions. These overflow commands and events are necessary for properly deriving larger width Counters from smaller widths. :: interface Counter<precision_tag,size_type> { async command size_type get(); async command bool isOverflowPending(); async command void clearOverflow(); async event void overflow(); } get() return the current time. isOverflowPending() return TRUE if an overflow interrupt will occur after the outermost atomic block is exits. FALSE otherwise. clearOverflow() cancel the pending overflow interrupt. 107 overflow() signals that an overflow in the current time. That is, the current time has wrapped around from its maximum value to zero. Alarm -------------------------------------------------------------------Alarm components are extensions of Counters that signal an event when their Compare register detects the alarm time has been hit. All commands and events of the Alarm interface are asynchronous (or in "interrupt context"). The Alarm interface provides a set of "basic" commands for common usage and provides a set of "extended" commands for advanced use. :: interface Alarm<precision_tag,size_type> { // basic interface async command void start( size_type dt ); async command void stop(); async event void fired(); // extended interface async command bool isRunning(); async command void startAt( size_type t0, size_type dt ); async command size_type getNow(); async command size_type getAlarm(); } start(dt) cancel any previously running alarm and set to fire in dt time units from the time of invocation. The alarm will only fire once then stop. stop() cancel any previously running alarm. fired() signals that the alarm has occurred. isRunning() return TRUE if the alarm has been started and has not been cancelled or has not yet fired. FALSE is returned otherwise. startAt(t0,dt) cancel any previously running alarm and set to fire at time t1 = t0+dt. This form allows a delay to be anchored to some time t0 taken before the invocation of start. This is also the form used internally in the timer subsystem to allow the use of the full width of an alarm while being able to detect if the alarm time for a short alarm prematurely elapsed. getNow() return the current time in the precision and width of the alarm. getAlarm() 108 TEP102: Timers return the time the currently running alarm will fire or the time that the previously running alarm was set to fire. BusyWait -------------------------------------------------------------------The BusyWait interface replaces the TOSH_uwait macro from TinyOS 1.x. :: interface BusyWait<precision_tag,size_type> { async command void wait( size_type dt ); } wait(dt) block for no less than the specified amount of time. LocalTime -------------------------------------------------------------------The LocalTime interface exposes a 32-bit counter without overflow utilities. This is primarily for application code that does not care about overflow conditions. :: interface LocalTime<precision_tag> { async command uint32_t get(); } get() return the current time. Timer -------------------------------------------------------------------All commands and events of the Timer interface are synchronous (or in "task context"). The Timer interface provides a set of "basic" commands for common usage and provides a set of "extended" commands for advanced use. The Timer interface allows for periodic events. :: interface Timer<precision_tag> { // basic interface command void startPeriodic( uint32_t dt ); command void startOneShot( uint32_t dt ); command void stop(); event void fired(); // extended interface command bool isRunning(); command bool isOneShot(); command void startPeriodicAt( uint32_t t0, uint32_t dt ); command void startOneShotAt( uint32_t t0, uint32_t dt ); 109 command uint32_t getNow(); command uint32_t gett0(); command uint32_t getdt(); } startPeriodic(dt) cancel any previously running timer and set to fire in dt time units from the time of invocation. The timer will fire periodically every dt time units until stopped. startOneShot(dt) cancel any previously running timer and set to fire in dt time units from the time of invocation. The timer will only fire once then stop. stop() cancel any previously running timer. fired() signals that the timer has occurred. isRunning() return TRUE if the timer has been started and has not been cancelled and has not fired for the case of one-shot timers. One a periodic timer is started, isRunning will return TRUE until it is cancelled. isOneShot() return TRUE if the timer is a one-shot timer. otherwise if the timer is a periodic timer. Return FALSE startPeriodicAt(t0,dt) cancel any previously running timer and set to fire at time t1 = t0+dt. The timer will fire periodically every dt time units until stopped. startOneShotAt(t0,dt) cancel any previously running timer and set to fire at time t1 = t0+dt. The timer will fire once then stop. getNow() return the current time in the precision and width of the timer. gett0() return the time anchor for the previously started timer or the time of the previous event for periodic timers. getdt() return the delay or period for the previously started timer. 3. HAL guidelines ==================================================================== Platforms typically select a clocking option for each of their hardware counters, based on their hardware design (e.g., the mica family of motes all run their hardware timer 0 at 32kHz, and the micaz 110 TEP102: Timers mote runs its timer 1 at cpu frequency/256). Platforms SHOULD expose the timing functionality of these timers using the Alarm and Counter interfaces, in the fashion described below. Platforms MAY expose the same hardware timer with different frequencies - use of conflicting frequences in the same program SHOULD produce compile-time errors. A hardware timer with precision *P* and width *W* SHOULD be exposed as a several components:: configuration CounterPW { provides interface Counter<TP, uintW_t>; } ... generic configuration AlarmPWC { provides interface Alarm<TP,uintW_t>; } ... and, except if *W* is 32:: configuration CounterP32 { provides interface Counter<TP, uint32_t>; } ... generic configuration AlarmP32C { provides interface Alarm<TP,uint32_t>; } ... Instantiating the Alarm... components provides a new Alarm independent of all prior instantiations. Instantiating such a component "consumes" a compare register from the corresponding hardware timer; when no more compare registers are available, instantiation SHOULD produce a compile-time error (see Appendix B for an example of how to achieve this). For example, the micaz platform includes an AlarmMilli8C and AlarmMilli32C components for timer 0 (one instantiation allowed), and Alarm32kHz16C and Alarm32kHz32C for timer 1 (three instantiations allowed). 4. HIL requirements ==================================================================== The following component MUST be provided on all platforms:: TimerMilliC BusyWaitMicroC TimerMilliC -------------------------------------------------------------------:: #define TIMERMILLIC_SERVICE ... configuration TimerMilliC { provides interface Init; provides interface Timer<TMilli>[uint8_t num]; 111 provides interface LocalTime<TMilli>; } A timer is allocated using unique(TIMERMILLIC_SERVICE) to obtain a new unique timer number. This timer number is used to index the TimerMilli parameterised interface. BusyWaitMicroC -------------------------------------------------------------------:: configuration BusyWaitMicroC { provides interface BusyWait<TMicro,uint16_t>; } BusyWaitMicroC allows applications to busy-wait for a number of microseconds. It’s use should be restricted to situations where the delay is small and setting a timer or alarm would be impractical, inefficient or insufficiently precise. 5. Utility components ==================================================================== A number of platform independent generic components are provided to help implementers and advanced users of the TinyOS timer system: * * * * * * AlarmToTimerC BusyWaitCounterC CounterToLocalTimeC TransformAlarmC TransformCounterC VirtualizeTimerC Appendices B and C show how these can be used to help implement the timer HAL and HIL. AlarmToTimerC -------------------------------------------------------------------AlarmToTimerC converts a 32-bit Alarm to a Timer. :: generic component AlarmToTimerC( typedef precision_tag ) { provides interface Timer<precision_tag>; uses interface Alarm<precision_tag,uint32_t>; } BusyWaitCounterC -------------------------------------------------------------------BusyWaitCounterC uses a Counter to block until a specified amount of time elapses. :: 112 TEP102: Timers generic component BusyWaitC( typedef precision_tag, typedef size_type @integer() ) { provides interface BusyWait<precision_tag,size_type>; uses interface Counter<precision_tag,size_type>; } CounterToLocalTimeC -------------------------------------------------------------------CounterToLocalTimeC converts from a 32-bit Counter to LocalTime. :: generic component CounterToLocalTimeC( precision_tag ) { provides interface LocalTime<precision_tag>; uses interface Counter<precision_tag,uint32_t>; } TransformAlarmC -------------------------------------------------------------------TransformAlarmC decreases precision and/or widens an Alarm. already widened Counter component is used to help. :: An generic component TransformAlarmC( typedef to_precision_tag, typedef to_size_type @integer(), typedef from_precision_tag, typedef from_size_type @integer(), uint8_t bit_shift_right ) { provides interface Alarm<to_precision_tag,to_size_type> as Alarm; uses interface Counter<to_precision_tag,to_size_type> as Counter; uses interface Alarm<from_precision_tag,from_size_type> as AlarmFrom; } to_precision_tag and to_size_type describe the final precision and final width for the provided Alarm. from_precision_tag and from_size_type describe the precision and width for the source AlarmFrom. bit_shift_right describes the bit-shift necessary to convert from the used precision to the provided precision. For instance to convert from an Alarm<T32khz,uint16_t> to an Alarm<TMilli,uint32_t>, the following TransformAlarmC would be created:: new TransformAlarmC( TMilli, uint32_t, T32khz, uint16_t, 5 ) TransformCounterC -------------------------------------------------------------------TransformCounterC decreases precision and/or widens a Counter. :: 113 generic component TransformCounterC( typedef to_precision_tag, typedef to_size_type @integer(), typedef from_precision_tag, typedef from_size_type @integer(), uint8_t bit_shift_right, typedef upper_count_type @integer() ) { provides interface Counter<to_precision_tag,to_size_type> as Counter; uses interface Counter<from_precision_tag,from_size_type> as CounterFrom; } to_precision_tag and to_size_type describe the final precision and final width for the provided Counter. from_precision_tag and from_size_type describe the precision and width for the source AlarmFrom. bit_shift_right describes the bit-shift necessary to convert from the used precision to the provided precision. upper_count_type describes the numeric type used to store the additional counter bits. upper_count_type MUST be a type with width greater than or equal to the additional bits in to_size_type plus bit_shift_right. For instance to convert from a Counter<T32khz,uint16_t> to a Counter<TMilli,uint32_t>, the following TransformCounterC would be created:: new TransformCounterC( TMilli, uint32_t, T32khz, uint16_t, 5, uint32_t ) VirtualizeTimerC -------------------------------------------------------------------VirtualizeTimerC uses a single Timer to create up to 255 virtual timers. :: generic component VirtualizeTimerC( typedef precision_tag, int max_timers ) { provides interface Init; provides interface Timer<precision_tag> as Timer[ uint8_t num ]; uses interface Timer<precision_tag> as TimerFrom; } Appendix A: Timer hardware on various microcontrollers ==================================================================== a. Atmega128 i. Two 8-bit timers, each allowing * 7 prescaler * Timer 0 can * One compare output pin, values (division by different powers of 2) use an external 32768Hz crystal register, with many compare actions (change clear counter, generate interrupt, etc) ii. Two 16-bit timers, each with 114 TEP102: Timers * * * * 5 prescaler values External and software clocking options Three compare registers (again with many actions) Input capture b. MSP430 i. Two 16-bit timers with * * * * One with three compare registers One with eight compare registers Each from distinct clock source Each with limited prescalers c. Intel PXA27x i. One fixed rate (3.25MHz) 32-bit timer with * 4 compare registers * Watchdog functionality ii. 8 variable rate 32-bit timers with * 1 associated compare register each * Individually selectable rates: 1/32768s, 1ms, 1s, 1us * Individually selectable sources: (32.768 external osc, 13 Mhz internal clock) iii. Periodic & one-shot capability iv. Two external sync events Appendix B: a microcontroller: Atmega 128 timer subsystem ==================================================================== The Atmega128 exposes its four timers through a common set of interfaces: * HplTimer<width> - get/set current time, overflow event, control, init * HplCompare<width> - get/set compare time, fired event, control * HplCapture<width> - get/set capture time, captured event, control, config Parameterising these interfaces by width allows reusing the same interfaces for the 8 and 16-bit timers. This simplifies building reusable higher level components which are independent of timer width. :: interface HplAtm128Timer<timer_size> { /// Timer value register: Direct access async command timer_size get(); async command void set( timer_size t ); /// Interrupt signals async event void overflow(); //<! Signalled on overflow interrupt /// Interrupt flag utilites: Bit level set/clr 115 async async async async async command command command command command void void void bool bool reset(); start(); stop(); test(); isOn(); //<! //<! //<! //<! //<! Clear the overflow interrupt flag Enable the overflow interrupt Turn off overflow interrupts Did overflow interrupt occur? Is overflow interrupt on? /// Clock initialization interface async command void off(); async command void setScale( uint8_t scale); async command uint8_t getScale(); //<! Turn off the clock //<! Turn on the clock //<! Get prescaler setting } interface HplAtm128Compare<size_type> { /// Compare value register: Direct access async command size_type get(); async command void set(size_type t); /// Interrupt signals async event void fired(); /// Interrupt async command async command async command async command async command flag void void void bool bool //<! Signalled on compare interrupt utilites: Bit level set/clr reset(); //<! Clear the compare interrupt flag start(); //<! Enable the compare interrupt stop(); //<! Turn off comparee interrupts test(); //<! Did compare interrupt occur? isOn(); //<! Is compare interrupt on? } interface HplAtm128Capture<size_type> { /// Capture value register: Direct access async command size_type get(); async command void set(size_type t); /// Interrupt signals async event void captured(size_type t); /// Interrupt async command async command async command async command async command flag void void void bool bool //<! Signalled on capture int utilites: Bit level set/clr reset(); //<! Clear the capture interrupt flag start(); //<! Enable the capture interrupt stop(); //<! Turn off capture interrupts test(); //<! Did capture interrupt occur? isOn(); //<! Is capture interrupt on? async command void setEdge(bool up); //<! True = detect rising edge } These interfaces are provided by four components, corresponding to each hardware timer: HplAtm128Timer0C through HplAtm128Timer3C. The Atmega128 chip components do not define a HAL, as the timer configuration choices (frequencies, use of input capture or compare output, etc) are platform-specific. Instead, it provides a few generic components for converting the HPL interfaces into platform-independent interfaces. These generic components include appropriate configuration parameters 116 TEP102: Timers (e.g., prescaler values):: generic module Atm128AlarmC(typedef frequency_tag, typedef timer_size @integer(), uint8_t prescaler, int mindt) { provides interface Init; provides interface Alarm<frequency_tag, timer_size> as Alarm; uses interface HplTimer<timer_size>; uses interface HplCompare<timer_size>; } ... generic module Atm128CounterC(typedef frequency_tag, typedef timer_size @integer()) { provides interface Counter<frequency_tag,timer_size> as Counter; uses interface HplTimer<timer_size> as Timer; } ... Appendix C: a mote: Mica2 timer subsystem ==================================================================== The mica2 HAL exposes its four timers as follows: * Timer 0: divides the external 32768Hz crystal by 32 to build AlarmMilli8C and AlarmMilli32C (see Section 3). As timer 0 has a single compare register, these can only be instantiated once. Timing accuracy is as good as the external crystal. * Timer 1: the internal oscillator is divided by 8 to build AlarmMicro16C and AlarmMicro32C (see Section 3). 3 compare registers are available. The timing accuracy depends on how the mica2 is clocked: - internal 8MHz clock: depends on how well the clock is calibrated - external 7.37MHz crystal: times will be off by ~8.6% - selecting other clocking options will produce gross inaccuracy * Timer 2, 3: these timers are not currently exposed by the HAL. The mica2 HIL components are built as follows: * TimerMilliC: built using AlarmMilli32C (consuming its single compare register) * BusyWaitMicroC: implemented using a simple software busy-wait loop which waits for 8 cycles per requested microsecond. Accuracy is the same as with Timer 1. We include here as an example some of the source code for the above components: Bibliografia [1] Gps common view. Technical report. (disponibile a http://tf.nist.gov/ time/commonviewgps.htm). [2] The nist-f1 cesium fountain atomic clock. Technical report. (disponibile a http://tf.nist.gov/cesium/fountain.htm). [3] Texas instruments msp430x1xx family - user’s guide. Technical report. (disponibile a http://focus.ti.com/general/docs/lit/getliterature. tsp?literatureNumber=slau049f&fileType=pdf). [4] Two-way satellite time transfer (twstt). Technical report. (disponibile a http://tycho.usno.navy.mil/twstt_wh.html). [5] Iec61588: Precision clock - synchronization protocol for networked measurement and control systems (ieee standard). Technical Report 65C/333/FDIS, INTERNATIONAL ELECTROTECHNICAL COMMISSION, March 2004. [6] Global clock synchronization in sensor networks. IEEE Trans. Comput., 55(2):214–226, 2006. Qun Li and Daniela Rus, members. [7] Robert Szewczyk David Culler Alan Mainwaring, Joseph Polastre and John Anderson. Wireless sensor networks for habitat monitoring. In Proceedings of the First ACM Workshop on Wireless Sensor Networks and Applications, Atlanta, GA, USA, September 2002. [8] Deborah Estrin Lewis Girod Michael Hamilton Alberto Cerpa, Jeremy Elson and Jerry Zhao. Habitat monitoring: Application driver for wireless communication technology. In Proceedings of the 2001 ACM SIGCOMM Workshop on Data Communication in Latin American and the Caribbean, April 2001. (disponibile a http://www.isi.edu/scadds/papers/ CostaRica-oct01-final.ps). [9] Jean-Marc Berthaud. Time synchronization over networks using convex closures. IEEE/ACM Trans. Netw., 8(2):265–277, 2000. [10] Philipp Blum, Lennart Meier, and Lothar Thiele. Improved interval-based clock synchronization in sensor networks. In Third International Symposium on Information Processing in Sensor Networks, pages 349–358, Berkeley, California, USA, April 2004. 118 BIBLIOGRAFIA [11] Flaviu Cristian. Probabilistic clock synchronization. Distributed Computing, (3):146–158, 1989. [12] Jeremy Elson and Deborah Estrin. Time synchronization for wireless sensor networks. In Proceedings of the 2001 International Parallel and Distributed Processing Symposium (IPDPS), Workshop on Parallel and Distributed Computing Issues in Wireless Networks and Mobil Computing, pages 186–186, San Francisco, CA, USA, April 2001. [13] Jeremy Elson and Kay Römer. Wireless sensor networks: A new regime for time synchronization. In Proceedings of the First Workshop on Hot Topics in Networks (HotNets-I), Princeton, New Jersey, USA, 28 -29 October 2002. [14] Deborah Estrin, David Culler, Kris Pister, and Gaurav Sukhatme. Connecting the physical world with pervasive networks. IEEE Pervasive Computing, 1(1):59–69, 2002. [15] F.L.Lewis. Wireless sensor networks. In D.J.Cook and S.K.Das, editors, Smart Environments: Technologies, Protocols, and Applications. John Wiley, New York, 2004. [16] Floyd M. Gardner. Phaselock techniques. John Wiley & Sons, Inc., 2 edition, 1979. [17] Àkos Lédeczi György Balogh Branislav Kusy Gyula Simon, Miklòs Maròti, Andràs Nàdas, Gàbor Pap, Jànos Sallai, and Ken Frampton. Sensor networkbased countersniper system. In SenSys ’04: Proceedings of the 2nd international conference on Embedded networked sensor systems, pages 1–12, New York, NY, USA, 2004. ACM Press. [18] W. Su I.F. Akyldiz and Y. Sankarasasubramaniam. Wireless sensor networks: A survey. Computer Networks, 4(38):393–422, March 2002. [19] Lewis Girod Jeremy Elson and Deborah Estrin. Fine-grained network time synchronization using reference broadcasts. In OSDI ’02: Proceedings of the 5th symposium on Operating systems design and implementation, pages 147– 163, New York, NY, USA, 2002. ACM Press. [20] R.H. Katz J.M. Kahn and K.S.J.Pister. Next century challenges: mobile networking for smart dust. In Proceedings of the fifth annual ACM/IEEE international conference on Mobile computing and networking, pages 271–278, 1999. [21] Leslie Lamport. Time, clocks, and the ordering of events in a distributed system. Commun. ACM, 21(7):558–565, 1978. [22] Keith Marzullo and Susan Owicki. Maintaining time in a distributed server. Operating Systems Review, 3(19):44–54, July 1985. BIBLIOGRAFIA 119 [23] Edgar Nett Michael Mock, Reiner Frings and Spiro Trikaliotis. Continuous clock synchronization in wireless real-time applications. In SRDS ’00: Proceedings of the 19th IEEE Symposium on Reliable Distributed Systems (SRDS’00), page 125, Washington, DC, USA, 2000. IEEE Computer Society. [24] Gyula Simon Miklòs Maròti, Branislav Kusy and Àkos Lédeczi. The flooding time synchronization protocol. In SenSys ’04: Proceedings of the 2nd international conference on Embedded networked sensor systems, pages 39–49, New York, NY, USA, 2004. ACM Press. [25] David L. Mills. Internet Time Synchronization: The Network Time Protocol. Ieee computer society press edition, 1994. [26] David L. Mills. Adaptive hybrid clock discipline algortihm for the network time protocol. IEEE/ACM Transactions on Networking, 5(6):505–514, October 1998. [27] Giovanni Cherubini Nevio Benvenuto. Algorithms for Communications Systems and their Applications. Wiley, 2002. pag. 311-312. [28] L. Rodrigues P. Verı̀ssimo and A. Casimiro. Cesiumspray: a precise and accurate global time service for large-scale systems, 1997. [29] M.B. Srivastava S. Ganeriwal, R. Kumar. Network-wide time synchronization in sensor networks. NESL Technical Report, May 2003. [30] R. Kumar S. Ganeriwal and M. Srivastava. Timingsync protocol for sensor networks, 2003. [31] Michael Manzo Tanya Roosta Shankar Sastry. Time synchronization attacks in sensor networks. In SASN ’05, New York, NY, USA, 2005. ACM Press. [32] Hohyun Shim Vlasios Tsiatsis Saurabh Ganeriwal, Deepak Ganesan and Mani B. Srivastava. Estimating clock uncertainty for efficient duty-cycling in sensor networks. In SenSys ’05: Proceedings of the 3rd international conference on Embedded networked sensor systems, pages 130–141, New York, NY, USA, 2005. ACM Press. [33] Jana van Greunen and Jan Rabaey. Lightweight time synchronization for sensor networks. In WSNA ’03: Proceedings of the 2nd ACM international conference on Wireless sensor networks and applications, pages 11–19, New York, NY, USA, 2003. ACM Press. [34] Konrad Lorincz Thaddeus R. F. Fulford Jones Victor Shnayder, Borrong Chen and Matt Welsh. Sensor networks for medical care. In SenSys, page 314, 2005. [35] John R. Vig. Introduction to quartz frequency standards. Technical Report SLCET-TR-92-1 (Rev. 1), Army Research Laboratory, October 1992. (disponibile a http://www.ieee-uffc.org/freqcontrol/quartz/ vig/vigtoc.htm). 120 BIBLIOGRAFIA Ringraziamenti: bla bla bla