|
Appunti informatica |
|
Visite: 1564 | Gradito: | [ Grande appunti ] |
Leggi anche appunti:La domoticaLa domotica 1.1 Significato del termine La Rete telematicaUna RETE TELEMATICA consente di trasmettere e ricevere dati da un computer ad un Basi teoriche della trasmissione datiIl livello uno (Fisico) In questo capitolo verranno illustrati gli aspetti |
Il livello di rete è organizzato in due moduli: EnergyEfficiencyM e NetToSSM. Il primo si occupa del protocollo di risparmio energetico e fornisce i comandi invocabili dal modulo gestore del livello di rete, NetToSSM. L'interfaccia implementata tra i due moduli è EEtoNET e viene usata per gestire la modalità power-saving sui nodi; inoltre entrambi fanno uso di strutture dati per mantenere le informazioni riguardo ai canali passanti per ogni nodo. I dettagli sono descritti nel paragrafo 4.3.
La configurazione del network esporta verso i livelli superiori due interfacce, Connectionless e ConnectionOriented. La prima viene usata dal Query Executor, al livello applicazione, l'altra dallo Stream System, al livello di trasporto. All'interno di NetToSSM si utilizzano tabelle, per memorizzare i dati dei canali, e code gestite da task per l'invio e la ricezione dei messaggi.
Figura 19: configurazione del livello di rete (NetToSSC)
Il livello di rete garantisce l'invio e la ricezione di pacchetti attraverso funzionalità che offre ai livelli superiori, Stream System e Query Processor: i servizi realizzati verso questi due livelli sono una parte delle interfacce che il network implementa.
Le primitive disponibili sono quattro: connect, disconnect, send, asysend e ognuna realizza una specifica fase del protocollo di funzionamento. I primi tre comandi costruiscono (e si basano su) una comunicazione orientata alla connessione e fanno parte di un'interfaccia chiamata ConnectionOriented; il comando asysend invece viene utilizzato per spedire messaggi non legati ad una connessione (tipo UDP) e implementa l'altra interfaccia Connectionless. Il livello Stream System usa l'interfaccia Connection Oriented per inviare messaggi lungo canali di comunicazione costruiti tra i nodi, il Query Executor usa Connectionless per immettere i comandi nella rete e avviare l'esecuzione delle query.
L'operazione di connect viene invocata quando deve essere aperto un canale tra due nodi. I dati da passare alla primitiva sono: un intero a 16 bit che identifica l'indirizzo del nodo destinatario, un intero a 32 bit che indica il valore temporale al quale il canale dovrà garantire l'invio di dati, due interi a 8 bit che esprimono rispettivamente la lunghezza messaggio di livello Stream System e del payload del pacchetto di livello network; infine il puntatore a tale payload. Uno schema dei parametri è mostrato in tabella 4.
Nome parametro |
Descrizione |
dest |
Nodo destinatario: è necessario indicare verso quale nodo dovrà essere costruito il canale. |
streamrate |
Valore temporale in millisecondi: indica ogni quanto tempo il canale avrà bisogno della radio accesa. |
pktSS_size |
Questo parametro non è utilizzato. |
pMsg |
Puntatore al payload contenente il messaggio di livello Stream System. |
size |
Lunghezza del payload del pacchetto |
Tabella : parametri per la primitiva connect
In figura 20 è mostrato un esempio di comunicazione che avviene per una connect.
Il nodo A, che nell'esecuzione della query dovrà inviare i dati da processare sul nodo B, riceve la comunicazione di apertura di stream remoto verso quel nodo: a quel punto controlla di poter allocare una nuova entry in una tabella locale di canali e, se l'operazione riesce, aggiorna tale connessione con le informazioni sul prossimo hop per raggiungere il nodo B. Nel caso non sia possibile allocare una entry, l'operazione fallisce. L'ultimo intervento sulle strutture dati riguarda la tabella per l'energy efficiency: se tutto è andato bene si invoca un comando che provvede ad aggiornare quest'altra tabella, riservata ai tempi di accensione e spegnimento necessari per il corretto invio dei dati sui canali. Adesso il lavoro sul nodo A è terminato ed è necessario fare altrettanto sul nodo destinatario della comunicazione: un pacchetto di tipo connect viene costruito dal nodo A e inviato al nodo B, specificando le informazioni per una corretta allocazione nella tabella dei canali corrispondente.
Alla ricezione di un pacchetto di connect, un nodo alloca una entry nella tabella dei canali e una nella tabella per la gestione dell'energy efficiency: entrambe vengono aggiornate con le informazioni reperibili nel pacchetto. A questo punto, se il nodo che ha ricevuto il pacchetto non è il destinatario della connect provvede all'inoltro, modificando opportunamente l'indirizzo di livello MAC secondo la tabella di routing. Altrimenti il messaggio è arrivato alla meta e viene segnalato l'evento receive al livello superiore: il messaggio sarà gestito dallo Stream System.
Figura 20: costruzione di un canale tra due nodi (CONNECT)
Una volta che un canale è stato costruito, la spedizione dei messaggi tra due nodi avviene con l'invocazione del comando send, che serve per spedire un pacchetto lungo un canale specificato. Gli argomenti da passare all'invocazione della primitiva sono: un intero a 16 bit che identifica il canale sul quale si vuol comunicare, un intero a 8 bit che esprime la lunghezza del payload del messaggio e il puntatore al messaggio stesso. I parametri sono mostrati in tabella 5.
Nome parametro |
Descrizione |
channel_id |
Identificatore del canale sul quale si intende inviare dati con la send. |
pMsg |
Puntatore al payload del messaggio. |
size |
Lunghezza del payload del pacchetto. |
Tabella : parametri per la primitiva send
In figura 21 è mostrato un esempio di comunicazione su un canale.
Il nodo A che vuole inviare un pacchetto al nodo B utilizza la send sul canale specificato al momento dell'invocazione: in questo modo il pacchetto segue la rotta indicata per quel canale e viene inviato verso il prossimo hop seguendo l'associazione <destinatario-prossimo hop> per raggiungerlo. Quando il messaggio giunge sul nodo B l'unica operazione da fare è assicurarsi che il canale indicato dal pacchetto esista e sia attivo; dopodichè si segnala allo Stream System l'evento receive e il payload del pacchetto, che contiene i dati rilevati per la query, viene gestito opportunamente per comporre il risultato o una parte di esso.
Figura 21: invio di dati lungo un canale specificato (SEND)
La comunicazione tra i nodi va avanti finchè una esecuzione di query non viene interrotta dall'utente, generando un comando dal server verso uno dei nodi per la chiusura del canale. La primitiva per realizzare tale operazione è la disconnect ed è sufficiente invocarla passando il valore dell'identificatore di canale da cancellare, oltre naturalmente al valore della lunghezza del payload del messaggio e il puntatore a tale payload. I parametri per la primitiva sono descritti in tabella 6.
Nome parametro |
Descrizione |
channel_id |
Identificatore del canale che si vuole chiudere. |
pMsg |
Puntatore al payload del messaggio. |
size |
Lunghezza del payload del pacchetto. |
Tabella : parametri per la primitiva disconnect
Con l'invio di un pacchetto di disconnect, il canale indicato viene recuperato e cancellato dalla tabella dei canali; l'entry diviene nuovamente disponibile per nuove connessioni. Nel caso l'operazione abbia successo si provvede a rimuovere anche l'informazione sui tempi di accensione e spegnimento per quel canale nella tabella dell'energy efficiency.
Alla ricezione lungo tutto il cammino, il messaggio provoca la cancellazione della relativa struttura dati allocata e l'eventuale inoltro, fino al nodo destinatario, sul quale avviene la segnalazione dell'evento di ricezione al livello superiore, come possiamo vedere in figura 22.
Figura 22: cancellazione di un canale tra due nodi (DISCONNECT)
L'altro comando disponibile per la comunicazione tra i nodi è l'asysend. Questa primitiva viene invocata direttamente dal livello del Query Processor e serve sia per inviare un pacchetto proveniente dal server verso i nodi sia per inoltrare i risultati di una query dal sink verso il server. L'invocazione della primitiva richiede tre argomenti: il nodo destinatario, il puntatore al messaggio e il valore della misura del suo payload, come descritto in tabella 7.
Nome parametro |
Descrizione |
dest |
Identificatore del nodo con il quale si deve comunicare. |
pMsg |
Puntatore al payload del messaggio. |
size |
Lunghezza del payload del pacchetto. |
Tabella : parametri per la primitiva asysend
In figura 23 vediamo che l'invio di un pacchetto con questo comando avviene diversamente rispetto alla send: viene seguito infatti un routing diverso da quello specificato dai canali e i pacchetti seguono la strada che è indicata dalle tabelle di rotta (inviate dal server ai singoli nodi nella fase di inizializzazione). La comunicazione di cui si tratta avviene in modo asincrono rispetto all'interazione nodi-server sui canali relativa alla query e serve principalmente per l'invio dei comandi per la programmazione dei nodi e l'avvio della query.
Figura 23: invio asincrono di pacchetti (ASYSEND)
Su ogni nodo esistono due strutture dati principali per avere a disposizione informazioni sulla topologia della rete e quindi sulle comunicazioni coi nodi vicini: la tabella dei canali (channel_table) e la tabella di routing (routing_table).
La prima è un array di connection (connessioni) e serve per memorizzare su ogni nodo le connessioni presenti, così da inoltrare correttamente i pacchetti lungo i canali.
Ogni connessione è una struct di 5 byte formata da un identificatore univoco di canale, un byte che indica l'indirizzo di livello network del nodo destinatario, un byte che indica il prossimo hop per quel canale, infine un byte di cui 1 bit segnala se la connessione è attiva e gli altri 7 bit sono una chiave esterna verso un'altra tabella. Questi ultimi 7 bit sono un ulteriore identificatore che il network mantiene per la consistenza con la tabella relativa all'energy efficiency. Le strutture presenti in questa tabella sono riferite da questo campo con un identificatore di 7 bit: le operazioni di inserimento e cancellazione avvengono in conseguenza all'inserimento/cancellazione nella channel_table. In tabella 8 viene mostrata la struttura dati e i campi nel dettaglio.
Nome campo |
Lunghezza |
Descrizione |
channel_id |
16 bit |
Identificatore univoco di canale nella rete: è costruito a partire dall'indirizzo del nodo sorgente e da un contatore |
dest |
8 bit |
Indirizzo del nodo su cui il canale termina. E' possibile riferire fino a 256 possibili nodi |
succ |
8 bit |
Prossimo hop del canale: identifica il nodo sul quale sono indirizzati i pacchetti che viaggiano sul canale verso la destinazione |
validity |
1 bit |
Bit di controllo di validità del canale. Se è 0 significa che il canale non è attivo e non deve essere utilizzato. In questo stato può essere sovrascritto da un nuovo canale. Se è 1 significa che il canale è attivo. |
ee_position |
7 bit |
Chiave esterna: identificatore univoco della posizione del canale nella tabella connessioni del modulo di energy efficiency. Questi 7 bit permettono di riferire fino a 128 canali allocati dal modulo EnergyEfficiencyM. Questo valore viene restituito dalla funzione di allocazione set dell'interfaccia EEtoNET. |
Tabella : struct connection
L'altra struttura è la tabella dei vicini (routing_table) ed è un array di struct chiamate neighbor. Un neighbor è composto da 2 bytes: il primo è suddiviso in 1 bit che indica la validità dell'entry e i successivi 7 bit che sono l'identificatore del vicino; il byte che segue è suddiviso alla stessa maniera e il primo bit indica se il link relativo è bidirezionale, mentre i restanti 7 bit sono l'identificatore del prossimo hop, ovvero del nodo a cui inviare nel caso il destinatario di un pacchetto sia quello relativo alla entry. I campi della struttura sono descritti specificamente in tabella 9.
Nome campo |
Lunghezza |
Descrizione |
validity |
1 bit |
Bit di validità del link con il nodo vicino. Se 0 indica un link non valido o non più esistente; se 1 significa che il collegamento esiste ed è attivo. |
id |
7 bit |
Identificatore del nodo vicino: è possibile riferire fino a 128 vicini per ogni nodo. |
bidir_link |
1 bit |
Bit che indica se il link con il vicino è bidirezionale. Se 0 significa che il nodo può ricevere dal vicino id ma non necessariamente quello riceve dal nodo. Se 1 significa che il nodo e il vicino id hanno un link bidirezionale e si "sentono" reciprocamente. |
next_hop |
7 bit |
Identificatore del nodo verso il quale devono essere indirizzati i pacchetti con destinazione id. |
|
|
|
Tabella : struct neighbor
La tabella ha due funzioni a runtime: la prima è conservare le informazioni relative ai link con gli altri sensori per la fase di neighbor discovery e per la fase di costruzione dell'albero logico della rete; la seconda è funzionare da tabella di routing, una volta che il server ha inviato le informazioni riguardo alle rotte verso tutti gli altri nodi. Durante l'inizializzazione della rete la tabella conserva i dati dai soli vicini da cui riceve pacchetti. Pertanto la sua funzione è quella di aiutare alla costruzione del pacchetto Neighbor_report da inviare verso il server per contribuire alla composizione della tabella di routing. Il campo next_hop non ha utilità in questa fase. Successivamente, dopo aver ricevuto la routing_table, il nodo aggiorna completamente la tabella dei vicini inserendo i prossimi hop da compiere per raggiungere qualsiasi altro nodo.
Oltre a queste due tabelle esiste un altro tipo di struttura dati utilizzata nel network: è la coda (queue), definita come un array di messaggi di livello MAC (TOS_Msg), un campo lunghezza di un byte e un campo head anch'esso di un byte. I parametri della queue sono descritti in tabella 10.
Nome campo |
Lunghezza |
Descrizione |
elem [] |
8 bit |
Puntatore all'array: permette di riferire l'elemento desiderato della coda |
head |
8 bit |
Indice della posizione dell'elemento di testa nella coda |
length |
8 bit |
Lunghezza della coda |
Tabella : struct Queue |
Il network fa uso di code circolari: una per l'invio, OutQueue, una per la ricezione, InQueue, e una per la composizione dei messaggi, FreeQueue. Tutte e tre vengono modificate attraverso operazioni di inserzione (enqueue) e estrazione (dequeue) per inserire o togliere elementi dalla coda.
Ogni volta che si deve inviare un messaggio, si estrae un puntatore dalla coda libera (FreeQueue) e si costruisce il pacchetto; dopodichè, se non si incontrano situazioni di fallimento, si inserisce il puntatore al messaggio in questione nella coda dei messaggi in uscita (OutQueue). Se durante le operazioni sopra descritte avviene un fallimento e il messaggio non deve più essere inviato, si provvede a reinserire nella coda FreeQueue il puntatore al messaggio estratto precedentemente.
Attualmente non sono previste operazioni di estrazione messaggi dalla coda in uscita (OutQueue). Tali operazioni vengono fatte sulla InQueue nel momento in cui si deve analizzare il contenuto di un messaggio in arrivo. L'operazione di inserzione nella InQueue viene effettuata nell'handler dell'evento receive nel caso il messaggio sia da passare ai livelli superiori. L'operazione di estrazione risulta critica in quanto può restituire un puntatore ad un elemento nullo nel caso sia effettuata in una situazione di coda vuota e può portare a situazioni di fallimento: per questo è stata introdotta la variabile esterna pending che contribuisce a gestire l'utilizzo e le modifiche sulla coda, segnalando quando è in corso un'operazione. Questo flag viene modificato soltanto dalla procedura che si occupa di modificare le code, alla ricezione o alla spedizione di un messaggio: le procedure in questione sono i tasks.
Le code che gestiscono i messaggi in ingresso e in uscita da un nodo devono essere a loro volta amministrate correttamente per regolarne l'accesso e l'utilizzo: in particolare è essenziale che eventi asincroni non interrompano o modifichino un'operazione in corso su un elemento di una coda. Si conviene inoltre che la segnalazione di eventi avvenga in modo indivisibile rispetto ad altri eventi, per evitare il rischio che alcune strutture dati siano modificate.
La coda dei messaggi in arrivo, InQueue, è gestita dall'InQueueTask mentre quella dei messaggi in uscita, OutQueue, dall'OutQueueTask. Le istanze di queste particolari funzioni non possono essere eseguite in contemporanea realizzando di fatto una mutua esclusione fra task, indispensabile per la corretta elaborazione di alcune operazioni critiche sui messaggi.
L'InQueueTask viene chiamato ogni volta che si deve segnalare l'evento di ricezione ai livelli superiori. L'algoritmo è semplice: prende l'elemento nella posizione di testa della coda dei messaggi ricevuti e segnala l'evento su un'interfaccia, passando come argomento il puntatore al messaggio. Essendo questo algoritmo eseguito all'interno di un task, si ha la certezza che non sarà interrotto da altri task e il messaggio controllato non sarà modificato mentre l'operazione è in corso. L'InQueueTask viene invocato anche per segnalare l'evento connectDone: questa scelta è dovuta al fatto che attualmente non esiste un protocollo che prevede l'acknowledgement per i messaggi di connect; di conseguenza l'evento connectDone da segnalare deve essere simulato al momento dell'invio di un messaggio di connect. In corrispondenza della spedizione di un pacchetto di questo tipo emesso dal nodo stesso si genera perciò anche una segnalazione di connectDone allo Stream System.
L'OutQueueTask invece si occupa della spedizione dei messaggi: l'unico compito a cui adempie è l'estrazione di un messaggio dalla coda e la successiva chiamata del comando send dell'interfaccia SendMsg. Questa primitiva viene fornita dal modulo GenericComm e consente la trasmissione di un pacchetto sulla radio. Prima di realizzare l'invio vero e proprio il task pone la variabile pending a true per segnalare l'accesso bloccato alla struttura dati. Questo flag funziona da semaforo per la coda e verrà rimessa a false dall'handler dell'evento sendDone, generato verso il network una volta terminata la trasmissione oppure in caso di fallimento della chiamata, al fine di lasciare nuovamente libero l'accesso alla coda.
Il meccanismo di energy efficiency attua una gestione della radio mirata al risparmio di energia. L'idea principale è quella di memorizzare gli istanti di tempo in cui i canali sul nodo dovranno essere attivi, così da cercare eventuali finestre temporali in cui non occorre che la radio sia accesa per tali canali: in questo modo si intende sfruttare questi momenti per risparmiare la batteria dei sensori. Nel network è prevista una tabella di canali con i dati per il routing; nel modulo di energy efficiency si conservano le informazioni sui tempi in cui i vari canali sfruttano la radio per inviare o ricevere messaggi. La tabella channel_table viene riempita con una nuova entry ogni volta che una nuova connessione viene creata nel network.
Le entry di questa tabella sono chiamate channel e sono struct di 40 bytes contenenti 3 campi con valori temporali assoluti di 8 bytes ciascuno, corrispondenti rispettivamente a tempo di accensione, spegnimento e terminazione del canale; inoltre si hanno due valori di 4 bytes ciascuno rappresentanti la durata e il tempo di interarrivo dei dati su quel canale e infine un bit di validità. I valori nextON e nextOFF variano a tempo di esecuzione e sono aggiornati in base al tempo corrente sui sensori. La variabile interarrive deriva dalla query richiesta mentre duration è determinata in base a esperimenti e prove e misurabile attualmente in circa mezzo secondo. In realtà quest'ultima dovrebbe essere modificata in base alla lunghezza di un messaggio (più un messaggio è grande, maggiore è il tempo di trasmissione). Infine la variabile expiry, che pur essendo attualmente inutilizzata, va considerata nel caso il canale debba invalidarsi automaticamente a un certo istante di tempo. I campi della struct channel sono schematizzati in tabella 11.
Nome campo |
Lunghezza |
Descrizione |
active |
8 bit |
Bit di validità del canale. Se 0 il canale non è da considerare. In caso contrario i tempi relativi a accensione e spegnimento saranno considerati validi. |
duration |
32 bit |
Valore temporale in millisecondi che indica quanto la radio starà accesa per permettere al canale di inviare/ricevere dati. |
interarrive |
32 bit |
Valore temporale in millisecondi che indica ogni quanto tempo il canale avrà bisogno della radio accesa per inviare/ricevere dati. |
nextON |
64 bit |
Valore temporale in millisecondi che indica il prossimo istante assoluto in cui la radio dovrà riaccendersi per far si che il canale invii o riceva dati. |
nextOFF |
64 bit |
Valore temporale in millisecondi che indica il prossimo istante assoluto in cui la radio potrà spegnersi in quanto il canale non deve inviare o ricevere dati. |
expiry |
64 bit |
Campo attualmente inutilizzato. Indica l'istante di tempo in cui il canale dovrà cessare di esistere. |
Tabella : struct channel |
Questa struttura è sufficiente a raccogliere i dati necessari per il nostro obiettivo. Il bit di validità infatti indica se il canale è da tenere in considerazione oppure no; il valore della durata e dell'interarrivo, riferiti ai rilevamenti periodici che un sensore deve effettuare, ci permettono di costruire uno schema, variabile nel tempo, che ci mostra eventuali periodi durante i quali la radio del sensore può rimanere spenta senza perdere alcuna comunicazione.
Figura 24: esempio di schema di analisi per energy efficiency
In figura 24 è descritto un esempio in cui i canali presenti sul nodo sono due: ch_A e ch_B. Ciascuno ha i propri tempi necessari di radio ON e radio OFF, ovvero i tempi nei quali la radio dovrà stare accesa o spegnersi per usufruire di quel canale. Le frecce che vanno verso l'alto indicano l'accensione, quelle verso il basso lo spegnimento. Le linee tratteggiate significano che lo stato della radio non cambia in quel periodo di tempo.
Come possiamo vedere in figura 24 i tempi in cui la radio deve stare accesa per i canali si possono intersecare e lasciare altri intervalli vuoti: l'algoritmo cerca quegli istanti di tempo in cui non vi sia la necessità di radio accesa e li usa per spegnere il controller. In figura 24 queste eventuali pause sono limitate da due linee verticali che evidenziano rispettivamente i momenti in cui la radio non serve e in cui sarà invece necessario riaccenderla. Come possiamo notare, gli istanti in cui si modifica lo stato della ricetrasmittente non coincidono precisamente con gli istanti in cui i canali non ne hanno più bisogno: questa soglia di sicurezza, fissata attualmente nell'ordine di un secondo, anticipa le accensioni programmate e posticipa gli spegnimenti al fine di garantire che eventuali ritardi sulla rete non facciano perdere alcun messaggio. Il parametro di correzione è espresso in millisecondi ed è modificabile con il comando setRadioDelay dell'interfaccia EEtoNET: se per esempio è impostato a 1000 ms e un nodo deve accendere la radio all'istante t1=15000 e spegnerla all'istante t2=20000, le reali accensione e spegnimento della radio avverranno rispettivamente all'istante t1=14000 e t2=21000.
Un secondo accorgimento prevede che se il periodo che intercorre tra uno spegnimento e una riaccensione è troppo breve, e precisamente minore di una tolleranza fissata, la radio viene lasciata accesa in quanto il risparmio ricavato sarebbe praticamente nullo. Anche questa tolleranza si può impostare dall'esterno del modulo, con la chiamata al comando setTolerance: se per esempio viene impostato un valore uguale a k (di default è 1 secondo) la radio non viene spenta in tutti quei casi in cui la riaccensione sarebbe programmata entro k millisecondi.
Questi due comandi fanno parte dell'interfaccia EEtoNET, implementata dall'energy efficiency verso il network. Essa mette a disposizione anche le primitive startEE e stopEE con le quali si fa partire e si sospende l'algoritmo di power saving.
Al momento dell'invocazione di startEE si considerano i canali presenti sul nodo e si ricercano possibili intervalli di spegnimento. Tutto l'algoritmo viene coordinato attraverso timer che vengono attivati in corrispondenza dell'accensione della radio e allo scadere dei quali si analizza la situazione. Al momento della chiamata del comando stopEE invece la radio si accende e così rimane fino ad una nuova invocazione di startEE.
Ogni volta che un canale viene inserito dal network nella tabella dei canali viene creata una nuova entry in una tabella tramite la chiamata al comando set: l'aggiornamento dei tempi del canale avviene in base al tempo corrente e le altre informazioni sono prese direttamente dalla chiamata alla connect del network, in quanto presenti nella query stessa. In tabella 12 sono descritti i parametri per questa primitiva.
Nome campo |
Lunghezza |
Descrizione |
duration |
32 bit |
Durata del canale: indica quanto deve stare accesa la radio per permettere al canale in questione di inviare e ricevere dati |
interarrive |
32 bit |
Interarrivo: questo valore indica ogni quanto la radio dovrà riaccendersi per far funzionare il canale |
expiry |
64 bit |
Valore temporale di terminazione del canale: attualmente non previsto dall'applicazione |
Tabella : parametri per la primitiva set
La primitiva setSynch ha il solito compito ma viene invocata all'inizializzazione per creare un canale di sincronizzazione con il server: anche se ci troviamo in regime di energy efficiency la radio non si spegne mai per questo periodo. Tale connessione è fissa per ogni nodo e non può essere rimossa; tuttavia è possibile riprogrammarla con una nuova chiamata al comando setSynch.
Tutti gli altri canali invece possono essere invalidati con il comando reset che ne azzera il bit di validità rendendoli sovrascrivibili appena questo sarà necessario: infatti se un canale ha il bit di validità uguale a zero è come se non esistesse e la relativa entry della tabella può essere modificata coi valori di un nuovo canale. Infine il comando resetAll annulla in un'unica esecuzione tutti i canali eccetto quello di sincronizzazione.
L'interfaccia EEtoNET non prevede eventi: il modulo EnergyEfficiencyM la fornisce all'esterno implementando i comandi e il modulo NetToSSM la utilizza chiamando le primitive disponibili.
L'algoritmo che seleziona il tempo esatto per modificare lo stato della radio è invocato allo scadere di un timer: all'avvio del modulo di energy efficiency questo timer scatta e l'algoritmo imposta il primo istante da analizzare.
Il compito spetta alla funzione OffTimer: questa innanzitutto provvede ad aggiornare i valori presenti nella tabella in base al tempo corrente e poi considera l'istante di spegnimento più grande tra i dati relativi ai canali attivi sul nodo, prendendo in considerazione soltanto quelli minori rispetto ad un certo valore, che chiamiamo nextON, corrispondente al minimo dei tempi di prossima accensione per i canali attivi. Questi tempi sono calcolati addizionando i tempi di interarrivo ai tempi assoluti proxOn, relativi agli istanti passati di accensione.
In questo modo viene selezionato un valore offTime "candidato" e l'indice del canale relativo a tale istante di spegnimento. A questo punto esistono diversi casi risultanti.
Figura 25: algoritmo OffTimer (caso 1)
Nel primo caso, mostrato in figura 25, abbiamo offTime > nextOn e la radio non deve essere spenta, a causa di un altro canale. Le variabili vengono aggiornate e il timer per la programmazione dello spegnimento viene posticipato.
Figura 26: algoritmo OffTimer (caso 2)
Nel secondo caso, mostrato in figura 26, troviamo nextOn > offTime ma la differenza tra i due valori è minima, e in particolare è minore della tolleranza prevista. Il comportamento che si segue è analogo a quello del caso 1.
Figura 27: algoritmo OffTimer (caso 3)
Infine l'ultima situazione, mostrata in figura 27: nextOn > offTime e la differenza tra i valori è abbastanza grande. In questo caso si procede allo spegnimento della radio, si aggiornano le variabili e si fa partire un nuovo timer che dovrà scadere all'istante nextOn trovato. L'evento sollevato alla scadenza di questo timer provocherà la riaccensione della radio e un nuovo aggiornamento dei tempi.
Questi tre casi coprono tutte le eventuali situazioni derivate dall'analisi dell'algoritmo: in tutti i casi OffTimer restituisce come risultato un valore temporale e avvia un apposito timer, sia che la radio debba essere spenta, sia che lo spegnimento debba essere posticipato, sia che la radio vada riaccesa dopo un periodo di stop.
La tesi ha sviluppato e portato a completamento due compiti importanti per un livello di rete: il primo è la gestione multi-hop della rete stessa, che permette di estendere un gruppo di sensori ben oltre il raggio di copertura di ognuno di essi; il secondo, più specifico per le reti di sensori, è la gestione del risparmio energetico sui nodi.
Il lavoro svolto è iniziato da uno strato di rete single-hop ed ha avuto come obiettivo la realizzazione di uno strato di rete reale ed efficiente multi-hop. Le funzionalità sono state testate con il simulatore Tossim [1] per un ampia gamma di query di prova: grazie alle primitive implementate adesso è possibile costruire una rete con un grafo connesso qualsiasi. Inoltre i test effettuati su sensori Mica2 e MicaZ [2] hanno dato esito positivo e confermato la correttezza delle soluzioni trovate.
Per quanto riguarda il risparmio della batteria è stato studiato un algoritmo per calcolare i tempi adatti agli spegnimenti della radio e le problematiche derivanti. I metodi utilizzati hanno permesso di sfruttare al meglio gli elementi già esistenti del TinyOS per cercare di limitare al massimo l'uso di energia sui sensori, risparmiando batteria sui dispositivi di rilevazione, sul processore e naturalmente sulla radio. I test svolti sul simulatore hanno dati esiti positivi; analogamente le prove effettuate sui sensori su query semplici hanno messo in evidenza un risparmio considerevole di energia, per i periodi in cui la radio rimane spenta. Questo risparmio è dovuto principalmente ai comandi impiegati per ridurre al minimo i consumi durante lo stato di sleep della radio e all'algoritmo, di cui si è parlato in precedenza, che analizza i rate degli stream e si occupa degli spegnimenti periodici dei dispositivi. Si prevede quindi un consistente allungamento del tempo di vita medio del sensore nei casi di utilizzo tipici del MaD-WiSe, ovvero con rilevazioni periodiche di dati con lunghi periodi di inattività: in queste circostanze infatti la radio si trova per lo più spenta e il risparmio energetico viene sfruttato consistentemente.
Appunti su: |
|
Appunti Nutrizione | |
Tesine Medicina | |