




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第6章 TinyOS網絡協議 6.1 概述 6.2 分發(fā)路由協議 6.3 匯聚型路由協議 6.4 CTP協議的實現 小結 6.1 概述路由協議一直是無線傳感器網絡研究的一個重要方向,在TinyOS 2.x中有兩種基本的多跳路由協議:分發(fā)路由協議(Dissemination Protocol)和匯聚型路由協議(Collection Protocol)。分發(fā)協議能夠可靠地傳送小數據項到網絡中的每一個節(jié)點;匯聚型路由協議可以把網絡中每個節(jié)點的小數據項傳遞到指定的根節(jié)點。本章主要介紹這兩種協議以及實現過程。6.2 分發(fā)路由協議分發(fā)協議主要用于實現共享變量的網絡一致性。網絡中的每個節(jié)點都保存有該共享變量
2、的一個副本。分發(fā)服務會通知節(jié)點該變量值更改的時間,同時交換數據包以達到整個網絡的一致性。在任意給定時刻,可能會有兩個節(jié)點的變量值不相同。但過一段時間后,不一致的節(jié)點數會越來越少,最終整個網絡都將同一于一個相同的變量值。分發(fā)協議具有以下幾個特點:分發(fā)協議能夠達到網絡的高度一致性,能有效避免臨時性通信鏈路失效以及高丟包率等網絡傳輸問題。分發(fā)協議要求在有鏈路連接的情況下確保能夠達到某個變量值一致。對于不同大小的數據項,分發(fā)協議的設計會有很大的不同。以下內容將講解分發(fā)協議的一系列接口和組件,以及具體的實現過程。6.2.1 相關接口和組件在TinyOS 2.x中為分發(fā)協議提供了實現,下面講解涉及到的重要
3、接口和組件。1. 分發(fā)協議的接口在分發(fā)協議中分發(fā)服務提供了兩個主要的接口:DisseminationValue接口和DisseminationUpdate接口。它們都位于“tinyos-2.x/tos/lib/net/”目錄下。(1) DisseminationValue接口。DisseminationValue接口適用于接收從網絡中分發(fā)過來的數據,在此接口中包含兩個命令函數和一個事件函數,其具體代碼如代碼6-1所示。【代碼6-1】 DisseminationValue.ncinterface DisseminationValue command const t* get();command
4、void set( const t* );event void changed();其中,各個函數的功能如下所述:DisseminationValue.get()命令獲取const類型的指針指向數據區(qū)域。DisseminationValue.set()命令允許節(jié)點改變其當前的變量值,并幫助節(jié)點給變量分配一個初始值。DisseminationValue.changed()觸發(fā)節(jié)點改變變量值的事件。(2) DisseminationUpdate接口。DisseminationUpdate接口用于產生分發(fā)的數據,此接口只包含一個命令函數,該命令有一個指針類型的參數,提供DisseminationUp
5、date接口的組件必須將數據賦值到自己分配的內存中,DisseminationValue接口必須觸發(fā)change()事件,以此作為對change()調用的響應。其接口定義如代碼6-2所示?!敬a6-2】 DisseminationUpdate.ncinterface DisseminationUpdate command void change(t* ONE newVal);2. 分發(fā)協議的組件在分發(fā)協議中有較多的組件,本文將講解比較重要的組件為DisseminatorC組件,該組件提供了DisseminationValue接口和DisseminationUpdate接口。該組件位于“tiny
6、os-2.x /tos/lib/net/drip”,其具體代碼如代碼6-3所示?!敬a6-3】 DisseminatorC.ncgeneric configuration DisseminatorC(typedef t, dip_key_t key) provides interface DisseminationValue;provides interface DisseminationUpdate;在DisseminatorC組件中提供了兩個參數:參數t和參數key。參數t:數據包結構類型,其大小必須能夠包含單個message_t包。參數key:即鍵值key,允許創(chuàng)建不同的Dissemin
7、atorC實例組件,類似于AM標識號可以虛擬化AM服務。該鍵值一般由unique()函數產生。6.2.2 分發(fā)協議的實現以下內容將實現任務描述6.D.1,使用分發(fā)協議進行小數據的發(fā)送接收,當節(jié)點收到分發(fā)者發(fā)送的數據時,點亮LED。需要以下幾個步驟:(1) 在“cygwinoptmytinyosapps”目錄下創(chuàng)建myDissemination子目錄。(2) 在myDissemination目錄下創(chuàng)建并編寫myDisseminationApp.nc文件(核心應用模塊)、myDisseminationC.nc文件(頂層配件)和BlinkToRadioMsg.h文件(定義相關數據結構體)。(3) 編
8、寫Makefile文件。1. 創(chuàng)建myDissemination文件夾參照6.3.2節(jié)創(chuàng)建MultihopOscilloscope文件夾的步驟創(chuàng)建myDissemination文件夾。創(chuàng)建完成后如圖6-1所示。圖6-1 myDissemination文件夾 2. 編寫程序(1) myDisseminationApp.nc。在myDisseminationApp.nc文件中列出了實現分發(fā)協議所需要的一系列組件以及組件與組件的關系,具體代碼如描述6.D.1 myDisseminationAppC.nc所示?!久枋?.D.1】 myDisseminationAppC.nc#define MYID 8
9、configuration myDisseminationAppC implementation components myDisseminationC;components MainC;myDisseminationC.Boot - MainC;components ActiveMessageC;myDisseminationC.RadioControl - ActiveMessageC;components DisseminationC;myDisseminationC.DisseminationControl - DisseminationC;components new Dissemi
10、natorC(uint16_t, 0 x2345) as Object16C;myDisseminationC.Value16 - Object16C;myDisseminationC.Update16 - Object16C;components LedsC;myDisseminationC.Leds - LedsC;components new TimerMilliC();myDisseminationC.Timer - TimerMilliC;components new AMSenderC(MYID);myDisseminationC.AMSend-AMSenderC;myDissem
11、inationC.Packet-AMSenderC;myDisseminationC.AMPacket-AMSenderC;components new AMReceiverC(MYID);myDisseminationC.Receive-AMReceiverC;(2) myDisseminationC.nc。在myDissemination文件中實現了小數據的分發(fā)協議,首先分發(fā)者獲得需要分發(fā)的數據,然后將數據發(fā)送到網絡中;接收者接收到數據后,按照接收到的數據不同點亮不同的LED,具體代碼如描述6.D.1 myDisseminationC.nc所示?!久枋?.D.1】 myDisseminat
12、ionC.nc#include #include “BlinkToRadio.h”module myDisseminationC usesinterface AMSend;interface Receive;interface Packet;interface AMPacket;interface Boot;interface SplitControl as RadioControl;interface StdControl as DisseminationControl;interface DisseminationValue as Value16;interface Disseminati
13、onUpdate as Update16;interface Leds;interface Timer;implementation uint16_t counter;am_addr_t DES = 0 x0003;/*點亮LED任務*/task void ShowCounter()if(counter&0 x1)call Leds.led0On();if(counter&0 x2)call Leds.led1On();if(counter&0 x4)call Leds.led2On();if(counter&0 x8)call Leds.led3On();event void Boot.bo
14、oted() /開啟無線電服務call RadioControl.start();event void RadioControl.startDone( error_t result ) if ( result != SUCCESS )call RadioControl.start();else/開啟分發(fā)服務call DisseminationControl.start();counter = 0;/開啟定時器call Timer.startPeriodic( 2000 );event void RadioControl.stopDone( error_t result ) ;event voi
15、d Timer.fired() message_t pkt;BlinkToRadioMsg* btrpkt;counter = counter+1;/設定分發(fā)值call Update16.change(&counter);btrpkt=(BlinkToRadioMsg*)call Packet.getPayload(&pkt,sizeof(BlinkToRadioMsg);btrpkt-nodeid = DES;btrpkt-num = counter;/發(fā)送數據if(call AMSend.send(AM_BROADCAST_ADDR,&pkt,sizeof(BlinkToRadioMsg)
16、= SUCCESS);/*發(fā)現分發(fā)值發(fā)生變化*/event void Value16.changed() const uint16_t* newVal = call Value16.get();counter = *newVal;/如果數據發(fā)送成功,觸發(fā)LED1閃爍event void AMSend.sendDone(message_t* Pkt,error_t err)call Leds.led0Toggle(); /接收部分event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) if(len=
17、sizeof(BlinkToRadioMsg)/獲得接收信息的負載BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)payload;/取出發(fā)送的數值counter = btrpkt-num;/觸發(fā)LED閃爍post ShowCounter();return msg;(3) BlinkToRadioMsg.h。在BlinkToRadioMsg.h文件中定義了myDisseminationC.nc文件中發(fā)送數據所使用的結構體。其具體代碼如描述6.D.1 BlinkToRadioMsg.h所示。【描述6.D.1】 BlinkToRadioMsg.h#ifndef
18、 _BLINKTORADIO_H#define _BLINKTORADIO_Htypedef nx_struct BlinkToRadioMsgnx_uint16_t nodeid;nx_uint16_t num;BlinkToRadioMsg;#endif3. 編寫Makefile文件在myDissemination文件夾下創(chuàng)建Makefile文件,并在Makefile文件中添加描述6.D.1 Makefile文件內容?!久枋?.D.1】 Makefile文件COMPONENT=myDisseminationAppCCFLAGS += -I$(TOSDIR)/lib/net -I%T/lib
19、/net/dripinclude $(MAKERULES)4. 分發(fā)協議可視化組件程序編譯成功后,在Cygwin下輸入“make cc2530 docs”命令生成可視化組件關系圖,如圖6-2所示。圖6-2 分發(fā)協議可視化組件 5. 實驗現象將程序燒寫至設備中(需要兩個設備),可以觀察有以下兩個現象:設備的LED1閃爍,說明數據發(fā)送成功。設備的LED1LED4逐個點亮,說明設備接收到不同的分發(fā)數據。6.3 匯聚型路由協議6.3.1 概述匯聚型路由協議是TinyOS中一種基于無線傳感器網絡應用的數據匯聚協議,此協議需要將網絡中的數據匯聚到某個節(jié)點上,由此節(jié)點來處理這些數據。在匯聚型路由協議中網絡中
20、的節(jié)點分為三大類:根節(jié)點、虛擬根節(jié)點和采集節(jié)點。根節(jié)點:網絡中的數據最終匯聚到的節(jié)點,此節(jié)點負責處理整個網絡中的數據。虛擬根節(jié)點:此節(jié)點除了采集數據之外還具有中繼傳輸功能,即當其他節(jié)點與根節(jié)點的距離超過了通信范圍時,其他節(jié)點將選擇在自己通信范圍內的具有中繼功能的節(jié)點作為自己下一條節(jié)點,并將此具有中繼功能的節(jié)點認為是自己的虛擬根節(jié)點。采集節(jié)點:此節(jié)點只負責采集數據,并把采集的數據發(fā)往根節(jié)點或虛擬根節(jié)點。匯聚型路由協議的數據傳輸過程如圖6-3所示。其中0號節(jié)點為根節(jié)點,1、3號節(jié)點為虛擬的根節(jié)點,2、4、5、6號節(jié)點為采集節(jié)點。在圖6-3中,當5號節(jié)點有數據需要被收集起來,它就把數據沿著樹向上發(fā)送
21、,經過3號和1號虛擬的根節(jié)點將數據發(fā)送至網絡中的根節(jié)點。根節(jié)點既可以接收虛擬根節(jié)點的數據也可以接收采集節(jié)點的數據;虛擬根節(jié)點既可以接收采集的節(jié)點的數據也可以接收其他虛擬根節(jié)點的數據,且在匯聚協議中只有根節(jié)點和虛擬根節(jié)點具有接收數據的功能,采集節(jié)點是不具有數據接收功能的。圖6-3 匯聚型路由協議 6.3.2 相關接口和組件1. 匯聚服務的接口在TinyOS 2.x匯聚服務中,一個節(jié)點可以有四種存在方式:生產者、消費者、偵聽者和網絡處理者。根據存在方式不同,使用不同的接口與匯聚服務的組件交互。在應用程序中,通過匯聚標識號可以將匯聚服務多元化,類似于無線通信中的AM標識號。其中,四種存在方式說明如下
22、:生產者:產生數據并將數據發(fā)送至根節(jié)點或虛擬根節(jié)點的節(jié)點稱為生產者。生產者使用Send接口把數據發(fā)送到匯聚樹的根節(jié)點。匯聚標識號作為實例化Send接口的參數。消費者:接收數據的節(jié)點稱為消費者,消費者也是一種虛擬根節(jié)點。偵聽者:無意中收到消息的節(jié)點稱為偵聽者。偵聽者使用Receive接口接收偷聽到的消息,匯聚標號作為實例化的Receive接口的參數。能夠處理正在傳遞過程中消息的節(jié)點稱為網絡處理者。這些網絡處理者使用Intercept接口接收并更新消息。匯聚標識號也作為實例化Intercept接口的參數。在以上的描述中所用的接口有Send接口、Receive接口、Intercept接口,除去這三個
23、接口還有一個比較重要的接口RootControl接口。(1) Send.nc。Send接口的主要功能是發(fā)送數據以及獲得數據負載的長度,此接口有4個命令函數,1個事件觸發(fā)函數,其接口如代碼6-4所示?!敬a6-4】 Send.nc#include #include interface Send command error_t send(message_t* msg, uint8_t len);command error_t cancel(message_t* msg);event void sendDone(message_t* msg, error_t error);command uint8
24、_t maxPayloadLength();command void* getPayload(message_t* msg, uint8_t len);其中,各個函數功能描述如下:send()函數主要功能是發(fā)送數據,它決定了發(fā)送數據的最大長度。cancel()函數主要功能是取消當前要發(fā)送的數據命令。sendDone()函數為觸發(fā)發(fā)送事件函數,如果發(fā)送成功則返回SUCCESS,失敗則返回FAIL。maxPayloadLength()函數主要功能是獲得負載數據的最大長度。getPayload()函數主要功能是獲得需要發(fā)送的數據以及發(fā)送數據的長度。(2) Receive.nc。Receive接口主要
25、功能是接收生產者的數據,此接口中只有一個函數,其具體代碼如代碼6-5所示。【代碼6-5】 Receive.ncinterface Receive event message_t* receive(message_t* msg, void* payload, uint8_t len);(3) Intercept.nc。Intercept接口主要功能是共網絡處理者接收并更新消息,此接口只有一個事件函數,其具體代碼如代碼6-6所示?!敬a6-6】 Intercept.ncinterface Intercept event bool forward(message_t* msg, void* payl
26、oad, uint8_t len);Intercept.forward事件的主要功能是當節(jié)點接收到一個要轉發(fā)的消息包時,匯聚服務應當觸發(fā)這個事件。如果該事件的返回值為FASLE,那么匯聚服務就不能轉發(fā)這個包。此接口允許更高層的組件檢查消息包的內部,如果這個消息包多余,或者消息包可以匯聚到已有消息包內,此時可以通過此接口事件對消息進行相應處理。(4) RootControl.nc。匯聚樹型路由協議的網絡是通過根節(jié)點以及到根節(jié)點的路徑構成的,其中根節(jié)點的設定是通過RootControl接口來設定的,RootControl接口中有三個命令函數,在此接口的具體代碼如代碼6-7所示。【代碼6-7】 Ro
27、otControl.ncinterface RootControl command error_t setRoot();command error_t unsetRoot();command bool isRoot();其中,setRoot命令和unsetRoot命令的調用必須返回SUCCESS,否則返回FAIL;而isRoot命令則是根據setRoot命令和unsetRoot命令的返回值來決定自己的返回值。具體使用如下:如果一個節(jié)點已經是根節(jié)點,并調用setRoot命令,則返回SUCCESS。如果setRoot命令返回SUCCESS,那么isRoot命令的調用必須返回TRUE。如果unset
28、Root命令的調用返回SUCCESS,那么isRoot命令必須返回FALSE。2. 匯聚服務組件匯聚服務主要通過CollectionC組件、CollectionSenderC組件和CollectionSenderP組件來進行匯聚服務的,具體介紹如下。(1) CollectionC.nc。匯聚服務必須提供CollectionC組件,并且大多數的匯聚協議的接口是由Collection組件來提供的,CollectionC組件的具體實現如代碼6-8所示。【代碼6-8】 CollectionC.ncconfiguration CollectionC provides interface StdContr
29、ol; interface Senduint8_t client; interface Receivecollection_id_t id; interface Receive as Snoopcollection_id_t; interface Interceptcollection_id_t id; interface Packet; interface CollectionPacket; interface CtpPacket; interface CtpInfo; interface CtpCongestion; interface RootControl; uses interfac
30、e CollectionIduint8_t client; interface CollectionDebug; implementation components CtpP; StdControl = CtpP; Send = CtpP; Receive = CtpP.Receive; Snoop = CtpP.Snoop; Intercept = CtpP; Packet = CtpP; CollectionPacket = CtpP; CtpPacket = CtpP; CtpInfo = CtpP; CtpCongestion = CtpP; RootControl = CtpP; C
31、ollectionId = CtpP; CollectionDebug = CtpP;在使用CollectionC組件時需要注意以下幾個方面:CollectionC組件不能在非根節(jié)點或虛擬根節(jié)點上觸發(fā)Receive.Receive事件。當一個數據包成功地到達根節(jié)點時,此組件才可能會觸發(fā)此事件。如果CollectionC組件接收到一個需轉發(fā)的數據包,且當前節(jié)點不是根節(jié)點,就可能會觸發(fā)Intercept.forward事件。如果CollectionC組件接收到一個本該由其他節(jié)點轉發(fā)的消息包,就可能會觸發(fā)Snoop.receive事件。用戶使用RootControl接口可以使節(jié)點稱為匯聚樹協議的根節(jié)
32、點。(2) CollectionSenderC.nc。CollectionSendC組件是一個通用組件,它提供了Send接口和Packet接口,并且兩個接口是通過CollectionSenderP來實現的,CollectionSenderC組件具體代碼如代碼6-9所示?!敬a6-9】 CollectionSenderC.ncgeneric configuration CollectionSenderC(collection_id_t collectid) provides interface Send; interface Packet; implementation components n
33、ew CollectionSenderP(collectid, unique(UQ_CTP_CLIENT); Send = CollectionSenderP; Packet = CollectionSenderP;(3) CollectionSenderP.nc。CollectionSenderP組件提供了兩個接口:Send接口和Packet接口。CollectionSenderP組件通過綁定Send接口和Packet接口到CollectionC組件上實現,CollectionSenderP組件的具體代碼如代碼6-10所示?!敬a6-10】 CollectionSenderP.ncgener
34、ic configuration CollectionSenderP(collection_id_t collectid, uint8_t clientid) provides interface Send; interface Packet; implementation components CollectionC as Collector; components new CollectionIdP(collectid); Send = Collector.Sendclientid; Packet = Collector.Packet; Collector.CollectionIdclie
35、ntid - CollectionIdP;6.4 CTP協議的實現6.4.1 CTP協議概述CTP協議是基于樹的匯聚協議,網絡中的某些節(jié)點將自己設置為根節(jié)點,而其他節(jié)點形成以此根節(jié)點為中心的路由樹。CTP協議有以下兩個特點:節(jié)點并不是向固定的根節(jié)點發(fā)送數據包,而是選擇虛擬根節(jié)點作為下一跳發(fā)送數據節(jié)點。虛擬根節(jié)點根據路由梯度形成到根節(jié)點的路由。CTP協議的總體架構由三部分組成:鏈路估計器、路由引擎以及轉發(fā)引擎。其協議總體架構如圖6-4所示。圖6-4 CTP總體架構 其中,各個部分的功能如下:鏈路估計器:位于最底層,負責估計節(jié)點與鄰居節(jié)點之間的單跳鏈路質量,并維護一個鄰居表。路由引擎:位于中間層,
36、使用鏈路估計器提供的信息,選擇到根節(jié)點傳輸代價最小的節(jié)點作為父節(jié)點,并維護一個路由表。轉發(fā)引擎:維護本地包和轉發(fā)包的發(fā)送隊列,選擇適當的時機把隊頭的包送給父節(jié)點。1. 鏈路估計器CTP的鏈路估計器主要由鏈路估計交換子協議LEEP(Link Estimation Exchange Protocol)來完成,節(jié)點使用LEEP來估計和交換其與鄰居節(jié)點間的鏈路質量信息。在TinyOS 2.x的CTP協議中,LEEP協議的實現是通過LinkEstimatorP組件來實現的。LinkEstimatorP組件的實現有兩種形式:一是標準的LE實現,其實現代碼在“mytinyos/tos/lib/net/le”
37、中。一種是更精確的4BITLE實現,其實現代碼在“mytinyos/tos/lib/net/4bitle”中。LE估計器和4BITLE估計器的實現在結構上大體相同,不同的是4BITLE估計器提取的物理層、鏈路層以及網絡層的反饋信息能夠提高鏈路估計的精確值。因此本書中采用4BITLE的估計器。該組件的具體代碼如代碼6-11所示?!敬a6-11】 LinkEstimatorP.ncmodule LinkEstimatorP provides interface StdControl; interface AMSend as Send; interface Receive; interface Li
38、nkEstimator; interface Init; interface Packet; interface CompareBit; uses interface AMSend; interface AMPacket as SubAMPacket; interface Packet as SubPacket; interface Receive as SubReceive; interface LinkPacketMetadata; interface Random; LinkEstimatorP組件除了發(fā)送和接收消息外,還可以通過收到的消息計算雙向通信鏈路質量,并通過判斷通信鏈路質量添加
39、和刪除鄰居節(jié)點。(1) 判斷通信鏈路質量。LinkEstimatorP組件通信鏈路質量的獲得是通過LinkEstimator接口來進行的。該接口提供了txAck( )、txNoAck( )和clearDLQ( )等命令,通過這些命令能根據到鄰居節(jié)點的數據傳輸成功與否來更新鏈路估計值。其中各個命令的作用如下。txAck:當節(jié)點接收到一個數據的確認幀后,表明接收一條數據成功,并且將更新此信息發(fā)送者和接收者之間的鏈路估計值。具體源碼如代碼6-12所示?!敬a6-12】 LinkEstimatorP.nccommand error_t LinkEstimator.txAck(am_addr_t nei
40、ghbor) neighbor_table_entry_t *ne;uint8_t nidx = findIdx(neighbor);if (nidx = INVALID_RVAL) return FAIL;ne = &NeighborTablenidx;ne-data_success+;ne-data_total+;if (ne-data_total = DLQ_PKT_WINDOW) updateDETX(ne); return SUCCESS; txNoAck:當節(jié)點沒有接收到數據的確認幀時,同樣也更新發(fā)送節(jié)點與接收節(jié)點的鏈路估計值。具體源碼如代碼6-13所示?!敬a6-13】 Link
41、EstimatorP.nccommand error_t LinkEstimator.txNoAck(am_addr_t neighbor) neighbor_table_entry_t *ne;uint8_t nidx = findIdx(neighbor);if (nidx = INVALID_RVAL) return FAIL;ne = &NeighborTablenidx;ne-data_total+;if (ne-data_total = DLQ_PKT_WINDOW) updateDETX(ne);return SUCCESS;clearDLQ:當參數改變時,清除原來數據的鏈路估計
42、值。具體源碼如代碼6-14所示?!敬a6-14】 LinkEstimatorP.nccommand error_t LinkEstimator.clearDLQ(am_addr_t neighbor) neighbor_table_entry_t *ne;uint8_t nidx = findIdx(neighbor);if (nidx = INVALID_RVAL) return FAIL;ne = &NeighborTablenidx;ne-data_total = 0;ne-data_success = 0;return SUCCESS;(2) 鄰居節(jié)點的添加。鄰居節(jié)點的添加是通過Lin
43、kPacketMetadata接口來進行的,通過此接口判斷信道是否具有較高的鏈路質量,并把鄰居節(jié)點加入到鄰居表中,便于以后在選擇路徑時考慮該鄰居節(jié)點的鏈路。其實現代碼如代碼6-15所示?!敬a6-15】 LinkEstimatorP.ncif (call LinkPacketMetadata.highChannelQuality(msg) if (signal CompareBit.shouldInsert(msg, call Packet.getPayload(msg, call Packet.payloadLength(msg),call Packet.payloadLength(msg)
44、 nidx = findRandomNeighborIdx();if (nidx != INVALID_RVAL) signal LinkEstimator.evicted(NeighborTablenidx.ll_addr);initNeighborIdx(nidx, ll_addr);2. 路由引擎路由引擎負責計算到匯聚樹根節(jié)點的路由,即選擇數據傳輸的下一跳。它記錄了由鏈路估計表維護的一組節(jié)點路徑的期望傳輸值ETX(Expected Transmissions)。CTP是使用ETX作為路由梯度來表示雙向鏈路質量的估計值。ETX值越小表示鏈路質量越好。其中,根節(jié)點的路徑ETX為0,普通節(jié)點的
45、路徑ETX為其下一跳節(jié)點的路徑ETX加上他們之間鏈路的連接ETX,因此節(jié)點的路徑ETX是該節(jié)點到根節(jié)點之間整條路由的每跳連接ETX之和。路由引擎每隔一定事件就會根據更新的鏈路質量估計重新進行路由選擇,主要是計算路徑ETX和重選父節(jié)點,然后廣播一個路由幀,包括當前的父節(jié)點地址和路徑ETX。在TinyOS 2.x中CTP路由引擎的實現是通過CtpRoutingEngineP組件來實現的,其組件在“mytinyos/lib/net/ ctp/ CtpRoutingEngineP/”目錄下,具體實現代碼如代碼6-16所示?!敬a6-16】 CtpRoutingEngineP.ncgeneric mod
46、ule CtpRoutingEngineP(uint8_t routingTableSize,uint32_t minInterval,uint32_t maxInterval) provides interface UnicastNameFreeRouting as Routing;interface RootControl;interface CtpInfo;interface StdControl;interface CtpRoutingPacket;interface Init; uses interface AMSend as BeaconSend;interface Receive
47、 as BeaconReceive;interface LinkEstimator;interface AMPacket;interface SplitControl as RadioControl;interface Timer as BeaconTimer;interface Timer as RouteTimer;interface Random;interface CollectionDebug;interface CtpCongestion;interface CompareBit;在CtpRoutingEngineP組件中,通過LinkEstimator接口獲得鄰居表中的節(jié)點以及與
48、該鄰居節(jié)點的雙向鏈路質量。鏈路估計器和路由引擎之間的交流是通過LinkEstimator接口和CompareBit接口來進行的。在這兩個接口中,其命令函數返回的鏈路質量值都是標準形式。其中,LinkEstimator.getQuality()的返回值越小,表示該通信鏈路的質量越好。3. 轉發(fā)引擎轉發(fā)引擎主要負責以下5種功能:傳遞消息包到下一跳,在必要時重傳以及向鏈路估計器傳遞應答信號。決定何時向下一跳節(jié)點傳輸。檢測路由中的不一致,并通知路由引擎。維護需要傳輸的消息包隊列,該隊列混合了本地產生的消息包和需要轉發(fā)的消息包。檢測由應答信號丟失導致的單跳重復傳輸。在TinyOS 2.x中CTP協議的轉
49、發(fā)引擎是通過CtpForwarding EngineP組件來實現的,其組件在“mytinyos/lib/net/ctp/Ctp ForwardingEngineP/”目錄下,具體實現代碼如代碼6-17所示。【代碼6-17】 CtpForwardingEngineP.ncgeneric module CtpForwardingEngineP() provides interface Init;interface StdControl;interface Senduint8_t client;interface Receivecollection_id_t id;interface Receive
50、 as Snoopcollection_id_t id;interface Interceptcollection_id_t id;interface Packet;interface CollectionPacket;interface CtpPacket;interface CtpCongestion;uses interface AMSend as SubSend;interface Receive as SubReceive;interface Receive as SubSnoop;interface Packet as SubPacket;interface UnicastName
51、FreeRouting;interface SplitControl as RadioControl;interface Queue as SendQueue;interface Pool as QEntryPool;interface Pool as MessagePool;interface Timer as RetxmitTimer;interface LinkEstimator;interface Timer as CongestionTimer;interface Cache as SentCache;interface CtpInfo;interface PacketAcknowl
52、edgements;interface Random;interface RootControl;interface CollectionIduint8_t client;interface AMPacket;interface CollectionDebug;interface Leds;轉發(fā)引擎的3個關鍵函數分別是:消息接收/轉發(fā)函數、傳輸消息的任務函數和傳輸完畢后的處理函數。(1) 消息接收/轉發(fā)函數。消息接收函數由CtpForwardingEngineP組件的SubReceive.receive函數實現的,receive函數決定節(jié)點是否應當轉發(fā)當前接收的消息包。此函數有一個小的緩沖區(qū)保
53、存最近接收到的消息包,通過檢查這個緩沖區(qū)可以確定是否有重復的消息包,如果這個消息包有重復使用,就可以調用消息轉發(fā)forward函數。SubReceive.receive函數的具體實現如代碼6-18所示?!敬a6-18】 CtpForwardingEngineP.ncevent message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) collection_id_t collectid;bool duplicate = FALSE;fe_queue_entry_t* qe;uint8_t i, thl;co
54、llectid = call CtpPacket.getType(msg);thl = call CtpPacket.getThl(msg);thl+;call CtpPacket.setThl(msg, thl);call CollectionDebug.logEventMsg(NET_C_FE_RCV_MSG, call CollectionPacket.getSequenceNumber(msg), call CollectionPacket.getOrigin(msg), thl-);if (len call SubSend.maxPayloadLength() return msg;
55、if (call SentCache.lookup(msg) call CollectionDebug.logEvent(NET_C_FE_DUPLICATE_CACHE);return msg;if (call SendQueue.size() 0) for (i = call SendQueue.size(); -i;) qe = call SendQueue.element(i);if (call CtpPacket.matchInstance(qe-msg, msg) duplicate = TRUE;break;if (duplicate) call CollectionDebug.
56、logEvent(NET_C_FE_DUPLICATE_QUEUE);return msg;else if (call RootControl.isRoot()return signal Receive.receivecollectid(msg,call Packet.getPayload(msg, call Packet.payloadLength(msg), call Packet.payloadLength(msg);else if (!signal Intercept.forwardcollectid(msg, call Packet.getPayload(msg,call Packe
57、t.payloadLength(msg), call Packet.payloadLength(msg)return msg;else dbg(Route, Forwarding packet from %hu.n, getHeader(msg)-origin); return forward(msg);(2) 傳輸消息的任務函數。傳輸消息的任務函數由CtpForwardingEngineP組件的sendTask函數實現,sendTask函數會對需要轉發(fā)的消息包進行格式化,即重新組織消息包的內部結構。通過檢查收到的消息包,它可以判斷傳輸過程中是否存在路由循環(huán),并檢查傳輸隊列是否有空缺,如果傳輸
58、隊列已滿,丟棄該消息包并置位擁塞標識位;如果傳輸隊列為空,則提交sendTask任務,即直接發(fā)送出去,無需排隊。sendTask函數檢查位于傳輸隊列頭部的消息包,為下一條傳輸做好準備,即直接發(fā)送出去,無需排隊。(3) 消息處理完畢后的處理函數。消息處理完畢后的處理函數由CtpForwardingEngineP組件的sendDone函數實現,當傳輸完成后,sendDone函數檢查發(fā)送結果。有以下幾種情況:如果消息包發(fā)出后有收到應答信號,就從傳輸隊列中移除該消息包。如果消息包由本地節(jié)點產生,則把sendDone信號傳遞給上層組件。如果是轉發(fā)消息包,就把該消息包仍會到轉發(fā)消息的緩沖區(qū)。如果傳輸隊列中
59、還有剩余的消息包,例如已發(fā)送的消息包沒有得到應答,就啟動一個隨機定時器以重新提交sendTask任務。6.4.2 CTP協議實例以下內容將實現任務描述6.D.2,使用CTP協議實現數據的傳輸。完成此任務描述需要以下幾個步驟:(1) 在“mytinyos/apps”目錄下創(chuàng)建MultihopOscilloscope文件夾。(2) 在MultihopOscilloscope文件夾下創(chuàng)建并編寫MultihopOscilloscopeApp.nc文件和MultihopOscilloscopeC.nc文件。其中MultihopOscilloscopeApp.nc是頂層配置組件。(3) 編寫Makefil
60、e文件。1. 創(chuàng)建MultihopOscilloscope文件夾打開cygwin,在“mytinyos/apps”目錄下,輸入mkdir MultihopOscilloscope,創(chuàng)建文件夾,具體操作如圖6-5所示。圖6-5 創(chuàng)建MultihopOscilloscope文件夾 2. 創(chuàng)建并編寫主要組件在MultihopOscilloscope文件夾下創(chuàng)建MultihopOscilloscopeApp.nc文件和Multihop OscilloscopeC.nc文件。(1) MultihopOscilloscopeAppC.nc。在MultihopOscilloscopeApp.nc文件中主要列
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 加盟合同范本李慶亮
- 出售公司房屋合同范本
- 人壽第三方代理合同范本
- 企業(yè)策劃標準合同范本
- 公司常用合同范本
- 北京裝修裝修合同范本
- 產床買賣合同范本
- 單位辭退合同范本
- 分立合同范本
- 醫(yī)院車場保安合同范本
- 高新技術企業(yè)認定申請書樣例與說明
- 數據結構英文教學課件:chapter6 Tree
- 高壓氧科工作總結高壓氧科個人年終總結.doc
- 《政治學概論》教學大綱
- 橋梁缺陷與預防
- 食品生物化學習題謝達平(動態(tài))
- 新蘇教版小學科學三年級下冊全冊教案(2022年春修訂)
- 保安員工入職登記表
- 睿達RDCAM激光雕刻切割軟件V5.0操作說明書
- 機械設計基礎平面連桿機構課件
- 人力資源部經理崗位說明書
評論
0/150
提交評論