zstack的數據傳輸方式————組播、單播淺析

        最近在學習zigbee協議棧,對於zigbee的數據傳輸方式和流程不是很清楚,因此就狠花了幾天功夫去研究zigbee組網流程!首先,下面的分析是基於TI公司zstack自帶的例子程序——SampleApp。對SampleApp的應用層程序:SampleApp.c文件進行觀察,發現不管選中SampleApp例子程序的哪種設備(coordinator router 還是enddevice),SampleApp.c文件的內容基本上都相同,即每個設備都可以發送和接受兩種信息:週期信息(爲何coordinator、router、ednDevice都會週期發送信息,我們隨後會給出解釋,這裏先留個懸念)和閃爍信息。由於zstack組網過程不是講述的重點,因此就不過多的介紹SampleApp例程的組網流程,如果用到的話再講。

         這裏直接進入SampleApp_Init()函數,該函數是SampleApp例程的應用層初始化的入口。語句:

if ( readCoordinatorJumper() )
    zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
  else
    zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;

的意思是:通過判斷傳感器節點的跳線來判斷該節點是coordinator還是router。

繼續往下走看到下面的語句:


這個是節點發送週期信息的配置,其中第一行的addrMode = (afAddrMode_t)AddrBroadcast表示設備發送信息的方式是廣播。而第三行的shortAddr=0xFFFF表示設備會將信息廣播到網絡上的所有設備。至於爲何是shortAddr爲0xFFFF表示廣播到網絡上的所有設備,這不解釋了!




程序繼續往下走,可以看到下列的語句:


這些語句是發送閃爍信息的配置。


程序繼續往下走,可以看到下列語句:


同志們,這裏可以看到,所有的設備都默認在組1裏面。


在zigbee協議棧中,最最重要的就是任務事件的處理,zstack只要有需要處理的信息,首當其衝需要想到的就是事件處理函數,這裏也一樣,在初始化函數SampleApp_Init()執行後,接下來要執行的就是函數:uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ),這個函數的參數events就對應了相關的事件。這裏我們學習的是數據傳輸過程,所以第一步是先要形成一個WSN的網絡,而組網肯定會產生事件,而且這裏產生的還是系統事件,具體的事件爲ZDO_STATE_CHANGE。所以對應着SampleApp_ProcessEvent( uint8 task_id, uint16 events )函數的if ( events & SYS_EVENT_MSG )分支,該分支有個switch選擇,對應的case ZDO_STATE_CHANGE,在選項分支裏面,我們可以看到,不管設備是coordinator還是router還是endDevice,都會週期性(這裏使用的是定時)的發送信息,這就解釋了開始提出懸疑:爲何每種設備都會週期性的發送信息。具體代碼如下。



在case ZDO_STATE_CHANGE中,我們看到了SAMPLEAPP_SEND_PERIODIC_MSG_EVT,這也是事件,這個事件會導致下面的if語句運行:


進入該if語句的SampleApp_SendPeriodicMessage()函數,我們右鍵點擊該函數,選擇go to definition,下圖是SampleApp_SendPeriodicMessage()函數的主體:


可以發現SampleApp_SendPeriodicMessage()調用通信原語,換句話說,我們不能也不需要進入AF_DataRequest()的內部,只需要瞭解AF_DataRequest()函數每個參數的意義即可,AF_DataRequest()第一個參數表示設備需要發送信息到哪個目標地址,爲了找到第一個參數的具體值,我們需要搜索工程中的所有第一個參數的引用。具體方法是:依次點擊IAR的菜單欄的“edit” 下拉菜單的 "find and replaces" 的選項“"find in files",把SampleApp_Periodic_DstAddr複製出現的文本框,如下圖示:


在搜索到的信息中,我們可以找到下列信息:

SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast,該語句表明AF_DataRequest()是將信息發送到網絡上的所有設備!即週期性的信息發送方式是廣播方式。

到這裏我們就介紹了TI公司自帶的例程SampleApp的廣播信息發送過程!


而SampleApp實際上還有種數據傳輸方式爲組播,那組播的過程又是怎麼實現的呢?請繼續往下看!

在該例程中,組播的具體實現是對按鍵事件的響應。在SampleApp.c文件中,找到函數:void SampleApp_HandleKeys( uint8 shift, uint8 keys ),該函數是組播方式,

我們可以發現下列if語句:if ( keys & HAL_KEY_SW_1 ),該if語句的意思是如果按下按鍵SW_1,則調用函數: SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ),按照之前的方法,進入SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION )函數的內部。該函數的內部同樣也調用了一個原語:AF_DataRequest,具體內容如下:



同樣,該原語的第一個參數表示信息發送的目標地址,即信息發送的方式是廣播還是組播還是點播,按照之前搜索原語參數的所有引用的過程,可以同樣得到SampleApp_Flash_DstAddr的所有引用,搜索到的SampleApp_Flash_DstAddr所有引用如下:



我們點擊第二個引用,得到:下列語句:從這裏就可以得到,如果有按鍵按下了,則該節點會發送組播的信息!



以上觀點純屬個人看法 ,歡迎各位留言!











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章