版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第6章Zstack協(xié)議棧6.1概述 6.2Zstack軟件架構(gòu)6.3HAL層分析6.4NWK層分析6.5Tools配置和分析6.6Profile層分析6.7ZDO層分析6.8API函數(shù)6.9APP層分析6.10OSAL運(yùn)行機(jī)制
理解Zstack軟件架構(gòu)。
掌握操作系統(tǒng)的運(yùn)行機(jī)制。
掌握Zstack各層的作用。
【描述6.D.】
使用Zstack協(xié)議棧進(jìn)行數(shù)據(jù)傳輸。
Zstack協(xié)議棧是德州儀器(TI)公司為Zigbee提供的一個(gè)解決方案,結(jié)合CC2530F256芯片可以完整的實(shí)現(xiàn)Zigbee。本章將對(duì)Zstack協(xié)議棧進(jìn)行分層剖析,以介紹其運(yùn)作原理,這是進(jìn)行Zstack應(yīng)用開發(fā)的基礎(chǔ)。6.1概述
Zstack協(xié)議棧符合Zigbee協(xié)議結(jié)構(gòu),由物理層、MAC層、網(wǎng)絡(luò)層和應(yīng)用層組成。如本書前面所述,物理層和MAC層由IEEE802.15.4定義,網(wǎng)絡(luò)層和應(yīng)用層由Zigbee聯(lián)盟定義。Zigbee聯(lián)盟將應(yīng)用層詳細(xì)劃分為應(yīng)用支持子層、應(yīng)用設(shè)備框架以及Zigbee設(shè)備對(duì)象等。
本節(jié)將詳細(xì)介紹Zigbee協(xié)議棧的結(jié)構(gòu)。6.2Zstack軟件架構(gòu)
6.2.1Zigbee協(xié)議棧的結(jié)構(gòu)
Zigbee協(xié)議棧的結(jié)構(gòu)可參考第2章的圖2-3,其中各層的功能如下:
物理層內(nèi)容:物理層定義了物理無線信道和MAC子層之間的接口,提供物理層數(shù)據(jù)服務(wù)單元(PD-SAP)和物理層管理服務(wù)(MLME-SAP)。
MAC(介質(zhì)接入控制子層):MAC層負(fù)責(zé)處理所有物理無線信道的訪問,并產(chǎn)生網(wǎng)絡(luò)信號(hào)、同步信號(hào);支持PAN連接和分離,提供兩個(gè)對(duì)等的MAC實(shí)體之間的可靠鏈路。
NWK(網(wǎng)絡(luò)層):網(wǎng)絡(luò)層是Zigbee協(xié)議棧的核心部分,網(wǎng)絡(luò)層主要實(shí)現(xiàn)節(jié)點(diǎn)加入或者離開網(wǎng)絡(luò)、接收或拋棄節(jié)點(diǎn)、路由查找及維護(hù)等功能。
APL(應(yīng)用層):Zigbee應(yīng)用層包括應(yīng)用支持子層APS、應(yīng)用程序框架AF、Zigbee設(shè)備對(duì)象ZDO等。
應(yīng)用支持子層APS:APS層在NWK層和APL層之間,提供APSDE-SAP和APSME-SAP兩個(gè)接口,兩個(gè)接口的主要功能如下:
APSDE-SAP提供在同一個(gè)網(wǎng)絡(luò)中的兩個(gè)或者更多的應(yīng)用實(shí)體之間(即端點(diǎn))的數(shù)據(jù)通信。
APSME-SAP提供多種服務(wù)給應(yīng)用對(duì)象ZDO,這些服務(wù)包括安全服務(wù)和綁定設(shè)備服務(wù),并維護(hù)管理對(duì)象的數(shù)據(jù)庫(即AIB)。
應(yīng)用程序框架AF:運(yùn)行在Zigbee協(xié)議棧上的應(yīng)用程序?qū)嶋H是廠商自定義的應(yīng)用對(duì)象,并且遵循規(guī)范(Profile)運(yùn)行在端點(diǎn)1~240上。設(shè)備對(duì)象層ZDO:遠(yuǎn)程設(shè)備通過ZDO請(qǐng)求描述信息,接收到這些請(qǐng)求時(shí),ZDO會(huì)調(diào)用配置對(duì)象獲取相應(yīng)的描述符值。ZDO通過APSME-SAP接口提供綁定服務(wù)。
6.2.2Zstack協(xié)議棧
Zstack協(xié)議??梢詮腡I的官方網(wǎng)站下載(截止本書出版時(shí),Zstack協(xié)議棧的最新版本為Zstack-CC2530-2.5.1a),其下載網(wǎng)址為,下載完成后,雙擊可執(zhí)行程序即可安裝。使用IAR8.10版本打開Zstack-CC2530-2.5.1a中的SampleApp工程,其協(xié)議棧代碼文件夾如圖6-1所示。
其中部分層的功能如下:
APP:應(yīng)用層目錄,用戶可以根據(jù)需求添加自己的任務(wù)。這個(gè)目錄中包含了應(yīng)用層和項(xiàng)目的主要內(nèi)容,在協(xié)議棧里面一般是以操作任務(wù)實(shí)現(xiàn)的。
圖6-1協(xié)議棧代碼文件夾
HAL:硬件驅(qū)動(dòng)層,包括與硬件相關(guān)的配置、驅(qū)動(dòng)以及操作函數(shù)。
OSAL:協(xié)議棧的操作系統(tǒng)。
Profile:AF層目錄,包含AF層處理函數(shù)。
Security&Services:安全服務(wù)層目錄,包含安全層和服務(wù)層處理函數(shù),比如加密。
Tools:工程配置目錄,包括空間劃分及ZStack相關(guān)配置信息。
ZDO:ZDO設(shè)備對(duì)象目錄。
ZMac:MAC層目錄,包括MAC層參數(shù)及MAC層的LIB庫函數(shù)回調(diào)處理函數(shù)。
Zmain:主函數(shù)目錄,包括入口函數(shù)及硬件配置文件。
Output:輸出文件目錄,由IAR自動(dòng)生成。
6.2.3Zigbee協(xié)議棧與Zstack的對(duì)比
Zigbee協(xié)議棧的結(jié)構(gòu)與Zstack協(xié)議棧的各層關(guān)系如表6-1所示。
表6-1Zigbee協(xié)議棧結(jié)構(gòu)與Zstack對(duì)比
注意:Zstack協(xié)議棧是一個(gè)半開源的協(xié)議棧,其中MAC層和ZMAC層的源碼沒有全部開源,關(guān)于他們的具體內(nèi)容,在實(shí)際的工程開發(fā)中也不需要詳細(xì)了解。
Zigbee的HAL層提供了開發(fā)板所有硬件設(shè)備(例如LED、LCD、KEY、UART等)的驅(qū)動(dòng)函數(shù)及接口。HAL文件夾為硬件平臺(tái)的抽象層,包含common、include和target三個(gè)文件夾,如圖6-2所示。6.3HAL層分析
圖6-2HAL層目錄
6.3.1Common文件夾
Common文件夾下包含有hal_assert.c和hal_dirvers.c兩個(gè)文件。其中hal_assert.c是聲明文件,用于調(diào)試,hal_dirvers.c是驅(qū)動(dòng)文件,如圖6-3所示。
圖6-3Common目錄
1.
hal_assert.c
在hal_assert.c文件中包含兩個(gè)重要的函數(shù):halAssertHandler()和halAssertHazardLights()。
(1)
halAssertHandler()函數(shù)為硬件系統(tǒng)檢測(cè)函數(shù)。如果定義了ASSERT_RESET宏,系統(tǒng)將調(diào)用HAL_SYSTEM_RESET復(fù)位,否則將調(diào)用halAaaertHazardLights()執(zhí)行閃爍LED命令。halAssertHandler()函數(shù)如下:
【函數(shù)6-1】halAssertHandler()
voidhalAssertHandler(void)
{
//如果定義了ASSERT_RESET宏定義
#ifdefASSERT_RESET
//系統(tǒng)復(fù)位
HAL_SYSTEM_RESET();
#else!definedASSERT_WHILE
//當(dāng)檢測(cè)到錯(cuò)誤時(shí),LED燈閃爍命令函數(shù)
halAssertHazardLights();
#else
while(1);
#endif
}
(2)
halAssertHazardLights()函數(shù)控制LED燈閃爍,根據(jù)不同的硬件平臺(tái)定義的LED的個(gè)數(shù)來決定閃爍的LED的不同。例如,CC2430和CC2530所使用的硬件平臺(tái)不同,決定了閃爍的LED不同,其主要代碼如下:
【代碼6-1】halAssertHazardLights()
//如果硬件平臺(tái)定義的LED的個(gè)數(shù)為1
#if(HAL_NUM_LEDS>=1)
//LED1閃爍
HAL_TOGGLE_LED1();
//如果硬件平臺(tái)定義的LED的個(gè)數(shù)為2
#if(HAL_NUM_LEDS>=2)
//LED2閃爍
HAL_TOGGLE_LED2();
//如果硬件平臺(tái)定義的LED的個(gè)數(shù)為3
#if(HAL_NUM_LEDS>=3)
//LED3閃爍
HAL_TOGGLE_LED3();
//如果硬件平臺(tái)定義的LED的個(gè)數(shù)為4
#if(HAL_NUM_LEDS>=4)
//LED4閃爍
HAL_TOGGLE_LED4();
#endif
#endif
#endif
#endif
2.
hal_drivers.c
hal_drivers.c文件中包含了與硬件相關(guān)的初始化和事件處理函數(shù)。此文件中有4個(gè)比較重要的函數(shù):硬件初始化函數(shù)Hal_Init()、硬件驅(qū)動(dòng)初始化函數(shù)HalDriverInit()、硬件事件處理函數(shù)Hal_ProcessEvent()和詢檢函數(shù)Hal_ProcessPoll()。
(1)
Hal_Init()函數(shù)是硬件初始化函數(shù),其功能是通過“注冊(cè)任務(wù)ID號(hào)”以實(shí)現(xiàn)在OSAL層注冊(cè),從而允許硬件驅(qū)動(dòng)的消息和事件由OSAL處理。其函數(shù)內(nèi)容為:
【函數(shù)6-2】Hal_Init()
voidHal_Init(uint8task_id)
{
//注冊(cè)任務(wù)ID
Hal_TaskID=task_id;
}
(2)
HalDriverInit()函數(shù)被main()函數(shù)調(diào)用,用于初始化與硬件設(shè)備有關(guān)的驅(qū)動(dòng)。HalDriverInit()函數(shù)的具體功能如下:
【函數(shù)6-3】HalDriverInit()
voidHalDriverInit(void)
{
//如果定義了定時(shí)器則初始化定時(shí)器
#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)
//在Zstack-CC2530-2.5.1a版本中移除了定時(shí)器的初始化,但不影響Zstack的運(yùn)行。
#error"Thehaltimerdrivermoduleisremoved."
#endif
//如果定義了ADC,初始化ADC
#if(definedHAL_ADC)&&(HAL_ADC==TRUE)
HalAdcInit();
#endif
//如果定義了DMA,初始化DMA
#if(definedHAL_DMA)&&(HAL_DMA==TRUE)
HalDmaInit();
#endif
//如果定義了AES,初始化AES
#if(definedHAL_AES)&&(HAL_AES==TRUE)
HalAesInit();
#endif
//如果定義了LCD,初始化LCD
#if(definedHAL_LCD)&&(HAL_LCD==TRUE)
HalLcdInit();
#endif
//如果定義了LED,初始化LED
#if(definedHAL_LED)&&(HAL_LED==TRUE)
HalLedInit();
#endif
//如果定義了UART,初始化UART
#if(definedHAL_UART)&&(HAL_UART==TRUE)
HalUARTInit();
#endif
//如果定義了按鍵,初始化KEY
#if(definedHAL_KEY)&&(HAL_KEY==TRUE)
HalKeyInit();
#endif
//如果定義了SPI,初始化SPI
#if(definedHAL_SPI)&&(HAL_SPI==TRUE)
HalSpiInit();
#endif
//如果定義了USB,初始化USB,只限CC2531
#if(definedHAL_HID)&&(HAL_HID==TRUE)
usbHidInit();
#endif
}
(3)
Hal_ProcessEvent()函數(shù)在APP層中的任務(wù)事件處理中被調(diào)用,用于對(duì)相應(yīng)的硬件事件作出處理,具體包括系統(tǒng)消息事件、LED閃爍事件、按鍵處理事件和睡眠模式等。
【函數(shù)6-4】Hal_ProcessEvent()
uint16Hal_ProcessEvent(uint8task_id,uint16events)
{
uint8*msgPtr;
(void)task_id;
//系統(tǒng)消息事件
if(events&SYS_EVENT_MSG)
{
msgPtr=osal_msg_receive(Hal_TaskID);
while(msgPtr)
{
osal_msg_deallocate(msgPtr);
msgPtr=osal_msg_receive(Hal_TaskID);
}
returnevents^SYS_EVENT_MSG;
}
//LED閃爍事件
if(events&HAL_LED_BLINK_EVENT)
{
#if(defined(BLINK_LEDS))&&(HAL_LED==TRUE)
HalLedUpdate();
#endif
returnevents^HAL_LED_BLINK_EVENT;
}
//按鍵處理事件
if(events&HAL_KEY_EVENT)
{
#if(definedHAL_KEY)&&(HAL_KEY==TRUE)
HalKeyPoll();
if(!Hal_KeyIntEnable)
{
osal_start_timerEx(Hal_TaskID,HAL_KEY_EVENT,100);
}
#endif
returnevents^HAL_KEY_EVENT;
}
//睡眠模式
#ifdefPOWER_SAVING
if(events&HAL_SLEEP_TIMER_EVENT)
{
halRestoreSleepLevel();
returnevents^HAL_SLEEP_TIMER_EVENT;
}
#endif
return0;
}
(4)
Hal_ProcessPoll()函數(shù)在main()函數(shù)中被osal_start_system()調(diào)用,用來對(duì)可能產(chǎn)生的硬件事件進(jìn)行詢檢。函數(shù)原型為:
【函數(shù)6-5】Hal_ProcessPoll()
voidHal_ProcessPoll()
{
//定時(shí)器詢檢
#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)
HalTimerTick();
#endif
//UART詢檢
#if(definedHAL_UART)&&(HAL_UART==TRUE)
HalUARTPoll();
#endif
//定時(shí)器詢檢
#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)
//在Zstack-CC2530-2.5.1a版本中移除了定時(shí)器的初始化,但不影響Zstack的運(yùn)行。
#error"Thehaltimerdrivermoduleisremoved."
#endif
//串口詢檢
#if(definedHAL_UART)&&(HAL_UART==TRUE)
HalUARTPoll();
#endif
//SPI詢檢
#if(definedHAL_SPI)&&(HAL_SPI==TRUE)
HalSpiPoll();
#endif
//USB詢檢(僅限CC2530)
#if(definedHAL_HID)&&(HAL_HID==TRUE)
usbHidProcessEvents();
#endif
//如果定義了休眠模式
#ifdefined(POWER_SAVING)
//允許在下一個(gè)事件到來之前進(jìn)入休眠模式
ALLOW_SLEEP_MODE();
#endif
}硬件驅(qū)動(dòng)初始化函數(shù)HalDriverInit()和硬件事件處理函數(shù)Hal_ProcessEvent()是Zigbee協(xié)議棧固有的,一般不需要作出較大范圍的修改,只需要直接使用即可。
6.3.2Include文件夾
Include文件夾主要包含各個(gè)硬件模塊的頭文件,主要內(nèi)容是與硬件相關(guān)的常量定義以及函數(shù)聲明,如圖6-4所示。
圖6-4Include目錄
表6-2Include目錄下頭文件類型
6.3.3Target文件夾
Target目錄下包含了某個(gè)設(shè)備類型下的硬件驅(qū)動(dòng)文件、硬件開發(fā)板上的配置文件、MCU信息和數(shù)據(jù)類型。本書采用的硬件平臺(tái)為CC2530,因此本節(jié)以硬件設(shè)備類型CC2530EB(EB是版本號(hào),表示的是評(píng)估版)為例進(jìn)行講解,如圖6-5所示。
注意:上述“CC2530EB”中的字符“EB”是TI公司的Zstack在某個(gè)硬件實(shí)現(xiàn)上的版本號(hào),例如,“BB”是電池版(BatteryBoard),“DB”是開發(fā)版(DevelopmentBoard),“EB”是評(píng)估版(EvaluateBoard)。
在CC2530EB文件夾下包含了三個(gè)子文件夾,分別是Config、Drivers、Includes,如圖6-6所示。
圖6-5Target文件夾
圖6-6CC2530EB文件夾
1.
Config文件夾
Config文件夾中包含了hal_board_cfg.h,在hal_board_cfg.h中定義了硬件CC2530硬件資源的配置,比如GPIO、DMA、ADC等。
在hal_board_cfg.h文件中可以定義開發(fā)板的硬件資源。以LED為例,TI官方的CC2530EB版本定義了兩個(gè)LED:LED1和LED2,其在hal_board_cfg.h中定義如下:
【代碼6-2】hal_board_cfg.h
//有關(guān)LED1宏定義
#defineLED1_BVBV(0)
#defineLED1_SBITP1_0
#defineLED1_DDRP1DIR
#defineLED1_POLARITYACTIVE_HIGH
//如果定義了HAL_BOARD_CC2530EB_REV17,則定義LED2和LED3
#ifdefined(HAL_BOARD_CC2530EB_REV17)
//有關(guān)LED2的宏定義
#defineLED2_BVBV(1)
#defineLED2_SBITP1_1
#defineLED2_DDRP1DIR
#defineLED2_POLARITYACTIVE_HIGH
//有關(guān)LED3的宏定義
#defineLED3_BVBV(4)
#defineLED3_SBITP1_4
#defineLED3_DDRP1DIR
#defineLED3_POLARITYACTIVE_HIGH
#endif
LED宏定義完成之后,設(shè)置LED的打開和關(guān)閉,其代碼在hal_board_cfg.h文件中,代碼如下:
【代碼6-3】hal_board_cfg.h
/*如果定義了HAL_BOARD_CC2530EB_REV17且沒有定義HAL_PA_LNA和HAL_PA_LNA_
CC2590,則定義LED的狀態(tài)*/
#ifdefined(HAL_BOARD_CC2530EB_REV17)&&!defined(HAL_PA_LNA)
&&!defined(HAL_PA_LNA_CC2590)
//打開LED1~LED3
#defineHAL_TURN_OFF_LED1()st(LED1_SBIT=LED1_POLARITY(0);)
#defineHAL_TURN_OFF_LED2()st(LED2_SBIT=LED2_POLARITY(0);)
#defineHAL_TURN_OFF_LED3()st(LED3_SBIT=LED3_POLARITY(0);)
#defineHAL_TURN_OFF_LED4()HAL_TURN_OFF_LED1()
//關(guān)閉LED1~LED3
#defineHAL_TURN_ON_LED1()st(LED1_SBIT=LED1_POLARITY(1);)
#defineHAL_TURN_ON_LED2()st(LED2_SBIT=LED2_POLARITY(1);)
#defineHAL_TURN_ON_LED3()st(LED3_SBIT=LED3_POLARITY(1);)
#defineHAL_TURN_ON_LED4()HAL_TURN_ON_LED1()
//改變LED1~LED3的狀態(tài)
#defineHAL_TOGGLE_LED1()st(if(LED1_SBIT){LED1_SBIT=0;}
else{LED1_SBIT=1;})
#defineHAL_TOGGLE_LED2()st(if(LED2_SBIT){LED2_SBIT=0;}
else{LED2_SBIT=1;})
#defineHAL_TOGGLE_LED3()st(if(LED3_SBIT){LED3_SBIT=0;}
else{LED3_SBIT=1;})
#defineHAL_TOGGLE_LED4()HAL_TOGGLE_LED1()
LED的設(shè)置根據(jù)開發(fā)板的不同,可以設(shè)置不同的LED,其設(shè)置過程如上所述。
2.
Drivers文件夾
在Drivers文件中定義了硬件資源的驅(qū)動(dòng)文件,所定義的硬件資源如表6-3所示。
表6-3硬件資源驅(qū)動(dòng)文件其中,以最常用的LED為例,在hal_led.c文件中提供了兩個(gè)封裝好的函數(shù),在應(yīng)用層可以直接調(diào)用,以控制LED,這兩個(gè)函數(shù)是:
HalLedSet(uint8leds,uint8mode)。
HalLedBlink(uint8leds,uint8numBlinks,uint8percent,uint16period)。
(1)
HalLedSet()函數(shù)用來控制LED的亮滅,該函數(shù)的原型如下:
【函數(shù)6-6】HalLedSet()
HalLedSet(uint8leds,uint8mode);
其中:
參數(shù)leds,指LED的名稱,取值可以是:
HAL_LED_1。
HAL_LED_2。
HAL_LED_3。
HAL_LED_4。參數(shù)mode,指LED的狀態(tài),取值可以為以下幾種情況:
打開LED:HAL_LED_MODE_ON。
關(guān)閉LED:HAL_LED_MODE_OFF。
改變LED狀態(tài):HAL_LED_MODE_TOGGLE。
以上數(shù)據(jù)定義在hal_led.h文件中。
(2)
HalLedBlink()函數(shù)是用來控制LED閃爍的,函數(shù)原型如下:
【函數(shù)6-7】HalLedBlink()
HalLedBlink(uint8leds,uint8numBlinks,uint8percent,uint16period)
其中:
參數(shù)leds,指LED的名稱,參數(shù)可以為:
HAL_LED_1。
HAL_LED_2。
HAL_LED_3。
HAL_LED_4。參數(shù)numBlinks,指閃爍次數(shù)。
參數(shù)percent,指LED亮和滅的所用事件占空比,例如亮和滅所用的事件比例為
1∶1,則占空比為100/2
=
50。
參數(shù)period,指LED閃爍一個(gè)周期所需要的時(shí)間,以毫秒為單位。
Zstack的NWK層負(fù)責(zé)的功能有:節(jié)點(diǎn)地址類型的分配、協(xié)議棧模板、網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)、網(wǎng)絡(luò)地址的分配的選擇等。在Zstack協(xié)議棧中,NWK層的結(jié)構(gòu)如圖6-7所示。6.4NWK層分析
圖6-7NWK層結(jié)構(gòu)
6.4.1節(jié)點(diǎn)地址類型的選擇
Zstack中地址類型有兩種:64位IEEE地址和16位網(wǎng)絡(luò)地址(在Zstack中也稱短地址或網(wǎng)絡(luò)短地址)。
64位IEEE地址:即MAC地址(也稱“長地址”或“擴(kuò)展地址”),是一個(gè)全球唯一的地址,一經(jīng)分配將跟隨設(shè)備一生,通常由制造商在設(shè)備出廠或安裝時(shí)設(shè)置,這些地址由IEEE組織來維護(hù)和分配。
16位網(wǎng)絡(luò)地址:是設(shè)備加入網(wǎng)絡(luò)后,由網(wǎng)絡(luò)中的協(xié)調(diào)器分配給設(shè)備的地址(也稱“短地址”),它在網(wǎng)絡(luò)中是唯一的,用來在網(wǎng)絡(luò)中鑒別設(shè)備和發(fā)送數(shù)據(jù)。對(duì)于協(xié)調(diào)器,網(wǎng)絡(luò)地址固定為0x0000。
Zstack協(xié)議棧聲明了讀取IEEE地址和網(wǎng)絡(luò)地址的函數(shù),函數(shù)的聲明可以在NLMEDE.h文件中看到,但是具體的函數(shù)實(shí)現(xiàn)是非開源的,在使用的時(shí)候直接調(diào)用即可。
【代碼6-4】NLMEDE.h
//讀取父節(jié)點(diǎn)的網(wǎng)絡(luò)地址
uint16NLME_GetCoordShortAddr(void);
//讀取父節(jié)點(diǎn)的物理地址
voidNLME_GetCoordExtAddr(byte*);
//讀取節(jié)點(diǎn)本身的網(wǎng)絡(luò)地址
uint16NLME_GetShortAddr(void);
//讀取自己的物理地址
byte*NLME_GetExtAddr(void);
6.4.2協(xié)議棧模板
Zstack協(xié)議棧模板由Zigbee聯(lián)盟定義,在同一個(gè)網(wǎng)絡(luò)中的設(shè)備必須符合相同的協(xié)議棧模板。Zstack協(xié)議棧使用了Zigbee聯(lián)盟定義的三種模板:Zigbee協(xié)議棧模板、ZigbeePRO協(xié)議棧模板和特定網(wǎng)絡(luò)模板。所有的設(shè)備只要遵循該協(xié)議,一般情況下,即使使用不同廠商的不同設(shè)備,同樣可以形成網(wǎng)絡(luò)。
另外,開發(fā)者為了開發(fā)具有特殊性的產(chǎn)品,可以向Zigbee聯(lián)盟申請(qǐng)自定義的模板,在Zstack協(xié)議棧中,開發(fā)者申請(qǐng)了兩種自定義模板。
協(xié)議棧模板由一個(gè)ID標(biāo)識(shí)符區(qū)分,此ID標(biāo)識(shí)符可以通過查詢?cè)O(shè)備發(fā)送的信標(biāo)幀獲得。在設(shè)備加入網(wǎng)絡(luò)之前,首先需要確認(rèn)協(xié)議棧模板的ID標(biāo)識(shí)符。在Zstack協(xié)議棧中,各種模板的ID標(biāo)識(shí)符的定義如下:
“特定網(wǎng)絡(luò)”模板的ID標(biāo)識(shí)符被定義為“NETWORK_SPECIFIC”,且模板ID標(biāo)識(shí)符為0。
“Zigbee協(xié)議?!蹦0宓腎D標(biāo)識(shí)符被定義為
“HOME_SPECIFIC”,且模板ID標(biāo)識(shí)符為1。其中,“Zigbee協(xié)議棧”模板常用于智能家居的控制。
“ZigbeePRO協(xié)議?!蹦0宓腎D標(biāo)識(shí)符被定義為“ZIGBEEPRO_SPECIFIC”,且模板ID標(biāo)識(shí)符為2。自定義模板的ID標(biāo)識(shí)符被定義為“GENERIC_STAR”和“GENERIC_TREE”,且模板ID標(biāo)識(shí)符被分別定義為3和4。從模板ID標(biāo)識(shí)符的定義來看,這兩個(gè)自定義模板分別是為星型網(wǎng)絡(luò)和樹型網(wǎng)絡(luò)專門定義的。三種模板的配置在nwk_globals.h文件中,代碼如下:
【代碼6-5】nwk_globals.h
//“特定網(wǎng)絡(luò)”模板ID
#defineNETWORK_SPECIFIC 0
//Zigbee協(xié)議模板ID
#defineHOME_CONTROLS 1
//ZigbeePRO模板ID
#defineZIGBEEPRO_PROFILE 2
//自定義模板ID
#defineGENERIC_STAR 3
//自定義模板ID
#defineGENERIC_TREE 4
//如果定義了ZIGBEEPRO,那么協(xié)議棧為ZIGBEEPRO模板
#ifdefined(ZIGBEEPRO)
#defineSTACK_PROFILE_IDZIGBEEPRO_PROFILE
#else
//如果沒有定義ZIGBEEPRO,那么協(xié)議棧為ZIGBEE模板
#defineSTACK_PROFILE_IDHOME_CONTROLS
#endif
6.4.3網(wǎng)絡(luò)參數(shù)配置
網(wǎng)絡(luò)參數(shù)配置包括對(duì)網(wǎng)絡(luò)類型參數(shù)、網(wǎng)絡(luò)深度和網(wǎng)絡(luò)中每一級(jí)可以容納的節(jié)點(diǎn)個(gè)數(shù)的配置。
網(wǎng)絡(luò)類型即網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu),包括星型網(wǎng)絡(luò)、樹型網(wǎng)絡(luò)和網(wǎng)狀型網(wǎng)絡(luò)。
網(wǎng)絡(luò)深度即路由級(jí)別,協(xié)調(diào)器位于深度0,協(xié)調(diào)器的一級(jí)子節(jié)點(diǎn)(即協(xié)調(diào)器的直屬子節(jié)點(diǎn))位于深度1,協(xié)調(diào)器的二級(jí)子節(jié)點(diǎn)(即協(xié)調(diào)器直屬子節(jié)點(diǎn)的子節(jié)點(diǎn))位于深度2……依次類推,在Zstack協(xié)議棧中定義MAX_NODE_DEPTH為網(wǎng)絡(luò)的最大深度。網(wǎng)絡(luò)中每一級(jí)可以容納的節(jié)點(diǎn)個(gè)數(shù),即在Zstack協(xié)議棧中規(guī)定的每一級(jí)的路由可以掛載的路由器或終端節(jié)點(diǎn)的個(gè)數(shù)。
1.網(wǎng)絡(luò)類型參數(shù)和網(wǎng)絡(luò)深度的設(shè)置
在Zstack協(xié)議棧中星型網(wǎng)絡(luò)、樹型網(wǎng)絡(luò)和網(wǎng)狀型網(wǎng)絡(luò)三種網(wǎng)絡(luò)類型的定義在nwk_globals.h文件中,其代碼如下:
【代碼6-6】nwk_globals.h—網(wǎng)絡(luò)類型的定義
/**********定義網(wǎng)絡(luò)類型***********/
//星型網(wǎng)
#defineNWK_MODE_STAR0
//樹型網(wǎng)
#defineNWK_MODE_TREE1
//網(wǎng)狀網(wǎng)
#defineNWK_MODE_MESH2在Zstack協(xié)議棧中定義的三種網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)分別在不同的模板下定義,且每一種模板下都定義了該網(wǎng)絡(luò)的網(wǎng)絡(luò)深度,具體定義在nwk_globals.h文件中,其代碼如下:
【代碼6-7】nwk_globals.h—網(wǎng)絡(luò)類型和網(wǎng)絡(luò)深度的定義
//如果協(xié)議棧模板為ZigbeePRO模板
#if(STACK_PROFILE_ID==ZIGBEEPRO_PROFILE)
//網(wǎng)絡(luò)的最大深度為20
#defineMAX_NODE_DEPTH 20
//定義網(wǎng)絡(luò)類型為網(wǎng)狀網(wǎng)絡(luò)
#defineNWK_MODE NWK_MODE_MESH
#defineSECURITY_MODE SECURITY_COMMERCIAL
#if(SECURE!=0)
#defineUSE_NWK_SECURITY 1//trueorfalse
#defineSECURITY_LEVEL 5
#else
#defineUSE_NWK_SECURITY 0//trueorfalse
#defineSECURITY_LEVEL 0
#endif
//如果協(xié)議棧模板定義為Zigbee協(xié)議棧模板
#elif(STACK_PROFILE_ID==HOME_CONTROLS)
//網(wǎng)絡(luò)的最大深度為5
#defineMAX_NODE_DEPTH 5
//定義網(wǎng)絡(luò)類型為網(wǎng)狀網(wǎng)絡(luò)
#defineNWK_MODE NWK_MODE_MESH
#defineSECURITY_MODE SECURITY_COMMERCIAL
#if(SECURE!=0)
#defineUSE_NWK_SECURITY 1//trueorfalse
#defineSECURITY_LEVEL 5
#else
#defineUSE_NWK_SECURITY 0//trueorfalse
#defineSECURITY_LEVEL 0
#endif
//如果模板為星型網(wǎng)絡(luò)的自定義模板
#elif(STACK_PROFILE_ID==GENERIC_STAR)
//網(wǎng)絡(luò)的最大深度為5
#defineMAX_NODE_DEPTH 5
//定義網(wǎng)絡(luò)類型為星型網(wǎng)絡(luò)
#defineNWK_MODE NWK_MODE_STAR
#defineSECURITY_MODE SECURITY_RESIDENTIAL
#if(SECURE!=0)
#defineUSE_NWK_SECURITY 1//trueorfalse
#defineSECURITY_LEVEL 5
#else
#defineUSE_NWK_SECURITY 0//trueorfalse
#defineSECURITY_LEVEL 0
#endif
//如果網(wǎng)絡(luò)模板為特定網(wǎng)絡(luò)模板
#elif(STACK_PROFILE_ID==NETWORK_SPECIFIC)
//網(wǎng)絡(luò)的最大深度為5
#defineMAX_NODE_DEPTH 5
//定義網(wǎng)絡(luò)類型為網(wǎng)狀型網(wǎng)絡(luò)
#defineNWK_MODE NWK_MODE_MESH
#defineSECURITY_MODE SECURITY_RESIDENTIAL
#if(SECURE!=0)
#defineUSE_NWK_SECURITY 1//trueorfalse
#defineSECURITY_LEVEL 5
#else
#defineUSE_NWK_SECURITY 0//trueorfalse
#defineSECURITY_LEVEL 0
#endif
#endif
2.每一級(jí)可以容納的節(jié)點(diǎn)個(gè)數(shù)的配置
在Zstack協(xié)議棧中,每一級(jí)路由可以容納的節(jié)點(diǎn)的個(gè)數(shù)的配置分為兩種情況。
一個(gè)路由器或者一個(gè)協(xié)調(diào)器可以連接的子節(jié)點(diǎn)的最大個(gè)數(shù)。
一個(gè)路由器或者一個(gè)協(xié)調(diào)器可以連接的具有路由功能的節(jié)點(diǎn)的最大個(gè)數(shù)。如果前者用C來表示,后者用R來表示,那么R為C的一個(gè)子集。另外,這兩個(gè)參數(shù)的設(shè)置與協(xié)議棧模板有關(guān)系,具體配置在nwk_globals.c文件中,其代碼如下:
【代碼6-8】nwk_globals.c
//如果協(xié)議規(guī)范為ZigbeePRO模板
#if(STACK_PROFILE_ID==ZIGBEEPRO_PROFILE)
//定義MAX_ROUTERS為默認(rèn)值
byteCskipRtrs[1]={0};
//定義MAX_ROUTERS為默認(rèn)值
byteCskipChldrn[1]={0};
//如果協(xié)議規(guī)范為Zigbee模板
#elif(STACK_PROFILE_ID==HOME_CONTROLS)
//定義協(xié)調(diào)器和每級(jí)路由器下攜帶的路由器節(jié)點(diǎn)個(gè)數(shù)為6
byteCskipRtrs[MAX_NODE_DEPTH+1]={6,6,6,6,6,0};
//定義協(xié)調(diào)器和每級(jí)路由器可以攜帶的節(jié)點(diǎn)個(gè)數(shù)為20個(gè)
byteCskipChldrn[MAX_NODE_DEPTH+1]={20,20,20,20,20,0};
//如果協(xié)議模板為自定義GENERIC_STAR模板
#elif(STACK_PROFILE_ID==GENERIC_STAR)
//定義協(xié)調(diào)器和每級(jí)路由器下攜帶的路由器節(jié)點(diǎn)個(gè)數(shù)為5
byteCskipRtrs[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
定義協(xié)調(diào)器和每級(jí)路由器下攜帶的節(jié)點(diǎn)個(gè)數(shù)為5
byteCskipChldrn[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
//如果協(xié)議規(guī)范為自定義GENERIC_STAR規(guī)范
#elif(STACK_PROFILE_ID==NETWORK_SPECIFIC)
//定義協(xié)調(diào)器和每級(jí)路由器下攜帶的路由器節(jié)點(diǎn)個(gè)數(shù)為5
byteCskipRtrs[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
//定義協(xié)調(diào)器和每級(jí)路由器下攜帶的路由器節(jié)點(diǎn)個(gè)數(shù)為5
byteCskipChldrn[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
以上代碼定義中將C和R分別定義為CskipChldrn和CskipRtrs數(shù)組中的元素值。在數(shù)組中元素0表示協(xié)調(diào)器下面掛載的節(jié)點(diǎn)或路由器節(jié)點(diǎn)的個(gè)數(shù),元素1表示路由器1級(jí)下面掛載的節(jié)點(diǎn)或路由器節(jié)點(diǎn)的個(gè)數(shù)。依次類推,元素n表示n級(jí)路由器下面掛載的節(jié)點(diǎn)或路由器節(jié)點(diǎn)的個(gè)數(shù)。例如CskipChldrn數(shù)組中的第一個(gè)元素為20,那么C=20;CskipRtrs數(shù)組中的第一個(gè)元素為6,那么R=6。這兩個(gè)參數(shù)的設(shè)置,有時(shí)會(huì)影響網(wǎng)絡(luò)地址的分配。在Zigbee網(wǎng)絡(luò)中,網(wǎng)絡(luò)地址的分配是由網(wǎng)絡(luò)中的協(xié)調(diào)器來完成的。在網(wǎng)狀型網(wǎng)絡(luò)中,網(wǎng)絡(luò)地址的分配是由協(xié)調(diào)器隨機(jī)地分配的。但是在樹型網(wǎng)絡(luò)中,網(wǎng)絡(luò)地址的分配遵循了一定的算法。
在ZigbeePRO協(xié)議棧模板中定義的CskipChldrn和CskipRtrs數(shù)組為默認(rèn)值,其定義代碼如下:
【代碼6-9】ZigbeePRO定義的CskipChldrn和CskipRtrs
//如果協(xié)議規(guī)范為ZigbeePRO模板
#if(STACK_PROFILE_ID==ZIGBEEPRO_PROFILE)
//定義MAX_ROUTERS為默認(rèn)值
byteCskipRtrs[1]={0};
//定義MAX_ROUTERS為默認(rèn)值
byteCskipChldrn[1]={0};當(dāng)在協(xié)議棧模板中使用的CskipChldrn和CskipRtrs數(shù)組為默認(rèn)值時(shí),網(wǎng)絡(luò)地址遵循隨機(jī)分配機(jī)制,對(duì)新加入的節(jié)點(diǎn)使用隨機(jī)地址分配,即當(dāng)一個(gè)節(jié)點(diǎn)加入時(shí),首先將接收到父節(jié)點(diǎn)的隨機(jī)分配的網(wǎng)絡(luò)地址,然后產(chǎn)生“設(shè)備聲明”(包含分配到的網(wǎng)絡(luò)地址和IEEE地址)發(fā)送至網(wǎng)絡(luò)中的其余節(jié)點(diǎn)。如果另一個(gè)節(jié)點(diǎn)有著同樣的網(wǎng)絡(luò)地址,則通過路由器廣播“網(wǎng)絡(luò)狀態(tài)-地址沖突”至網(wǎng)絡(luò)中的所有節(jié)點(diǎn)。所有發(fā)生網(wǎng)絡(luò)地址沖突的節(jié)點(diǎn)更改自己的網(wǎng)絡(luò)地址,然后再發(fā)起“設(shè)備聲明”檢測(cè)新的網(wǎng)絡(luò)地址是否沖突。終端設(shè)備不會(huì)廣播“地址沖突”,它們的父節(jié)點(diǎn)會(huì)幫助完成這個(gè)過程。如果一個(gè)終端設(shè)備發(fā)生了“地址沖突”,它們的父節(jié)點(diǎn)發(fā)送“重新加入”消息至終端設(shè)備,并要求其更改網(wǎng)絡(luò)地址。然后,終端設(shè)備再發(fā)起“設(shè)備聲明”檢測(cè)新的網(wǎng)絡(luò)地址是否沖突。
3.樹型網(wǎng)絡(luò)中網(wǎng)絡(luò)地址分配的算法
在Zigbee的樹型網(wǎng)絡(luò)中,網(wǎng)絡(luò)地址分配算法需要三個(gè)參數(shù):
網(wǎng)絡(luò)的最大深度,在Zstack協(xié)議中被定義為MAX_NODE_DEPTH,在此算法中用L表示。
路由器或協(xié)調(diào)器可以連接的子節(jié)點(diǎn)的最大個(gè)數(shù),在Zstack協(xié)議棧中被定義為CskipChldrn數(shù)組中元素的值,在此算法中用C表示。路由器或協(xié)調(diào)器可以連接的具有路由功能的子節(jié)點(diǎn)的最大個(gè)數(shù),在Zstack協(xié)議棧中被定義為CskipRtrs數(shù)組中的元素的值,在此算法中用R表示。
以上三個(gè)參數(shù)設(shè)置完成后,如果需要計(jì)算深度為d的網(wǎng)絡(luò)地址偏移量Cskip(d),則有如下計(jì)算公式:若L
=
6,C
=
20,R
=
6,那么計(jì)算深度d
=
1的網(wǎng)絡(luò)地址偏移量Cskip(1)為5181(十六進(jìn)制為143D),協(xié)調(diào)器網(wǎng)絡(luò)地址為0x0000,那么協(xié)調(diào)器下第一個(gè)路由器的網(wǎng)絡(luò)地址為0x0001,第二個(gè)路由器的網(wǎng)絡(luò)地址為0x0001
+
0x143D
=
0x143E。
Tools文件為工程設(shè)置文件目錄,比如信道、PANID、設(shè)備類型的設(shè)置,如圖6-8所示為Tools文件。6.5Tools配置和分析
圖6-8Tools文件在Tools文件中包含了五個(gè)子文件,分別是f8w2530.xcl文件、f8wConfig.cfg文件、f8wCoord.cfg文件、f8wEndev.cfg文件和f8wRouter.cfg文件。其中f8w2530.xcl為CC2530的配置文件,使用Zstack協(xié)議棧時(shí)不用修改此項(xiàng),在這里不做講解。
1.
f8wConfig.cfg文件
f8wConfig.cfg文件為Zstack協(xié)議棧的配置文件,在此文件中設(shè)置Zigbee使用的信道和Zigbee網(wǎng)絡(luò)PANID。其代碼如下:
【代碼6-10】f8wConfig.cfg
//信道設(shè)置
//0:868MHz0x00000001
//1-10:915MHz0x000007FE
//11-26:2.4GHz0x07FFF800
//-DMAX_CHANNELS_868MHz 0x00000001
//-DMAX_CHANNELS_915MHz 0x000007FE
//-DMAX_CHANNELS_24GHz 0x07FFF800
//以下為信道11-26的設(shè)置
//-DDEFAULT_CHANLIST=0x04000000//26-0x1A
-DDEFAULT_CHANLIST=0x02000000//25-0x19
//-DDEFAULT_CHANLIST=0x01000000//24-0x18
//-DDEFAULT_CHANLIST=0x00800000//23-0x17
//-DDEFAULT_CHANLIST=0x00400000//22-0x16
//-DDEFAULT_CHANLIST=0x00200000//21-0x15
//-DDEFAULT_CHANLIST=0x00100000//20-0x14
//-DDEFAULT_CHANLIST=0x00080000//19-0x13
//-DDEFAULT_CHANLIST=0x00040000//18-0x12
//-DDEFAULT_CHANLIST=0x00020000//17-0x11
//-DDEFAULT_CHANLIST=0x00010000//16-0x10
//-DDEFAULT_CHANLIST=0x00008000//15-0x0F
//-DDEFAULT_CHANLIST=0x00004000//14-0x0E
//-DDEFAULT_CHANLIST=0x00002000//13-0x0D
//-DDEFAULT_CHANLIST=0x00001000//12-0x0C
//-DDEFAULT_CHANLIST=0x00000800//11-0x0B
//網(wǎng)絡(luò)PANID的設(shè)置
-DZDAPP_CONFIG_PAN_ID=0xFFFF
Zigbee工作在2.4
GHz,在2.4
GHz上定義了16個(gè)信道,即11~26號(hào)信道,以上是工作在25號(hào)信道上的。當(dāng)需要修改信道時(shí),只需要將所需信道的注釋符“//
”去掉,將原來使用的信道注釋掉。
當(dāng)網(wǎng)絡(luò)PANID設(shè)置為0xFFFF時(shí),即協(xié)調(diào)器建立網(wǎng)絡(luò)時(shí)將在0x0000~0xFFFF之間隨機(jī)選擇一個(gè)數(shù)作為網(wǎng)絡(luò)的PANID。如果網(wǎng)絡(luò)的PANID為0x0000~0xFFFF之間指定的一個(gè)數(shù),則協(xié)調(diào)器建立網(wǎng)絡(luò)時(shí)將會(huì)以選定的PANID作為網(wǎng)絡(luò)PANID建立網(wǎng)絡(luò)。例如:
【示例6-1】f8wConfig.cfg
//網(wǎng)絡(luò)PANID的設(shè)置
-DZDAPP_CONFIG_PAN_ID=0x1234
示例6-1中設(shè)定網(wǎng)絡(luò)PANID為0x1234,那么協(xié)調(diào)器建立網(wǎng)絡(luò)后,將會(huì)選擇0x1234作為網(wǎng)絡(luò)PANID。
2.
f8wCoord.cfg文件
f8wCoord.cfg文件是Zstack協(xié)議棧協(xié)調(diào)器設(shè)備類型配置文件,其功能是將程序編譯成具有協(xié)調(diào)器和路由器的雙重功能(這是因?yàn)閰f(xié)調(diào)器需要同時(shí)具有網(wǎng)絡(luò)建立和路由器的功能),其代碼如示例6-2所示。
【示例6-2】f8wCoord.cfg
/*協(xié)調(diào)器設(shè)置*/
//協(xié)調(diào)器功能
-DZDO_COORDINATOR
//路由器功能
-DRTR_NWK
3.
f8wRouter.cfg文件
f8wRouter.cfg文件為路由器配置文件,此文件將程序編譯成具有路由器的功能,其代碼如示例6-3所示。
【示例6-3】f8wRouter.cfg
/*路由器設(shè)置*/
-DRTR_NWK
4.
f8wEndev.cfg文件
此文件為終端節(jié)點(diǎn)的配置文件,在此文件中既沒有編譯協(xié)調(diào)器的功能也沒有編譯路由器的功能,因此,此文件一般不需要配置。
Profile對(duì)應(yīng)Zigbee軟件架構(gòu)中的應(yīng)用程序框架AF層,其結(jié)構(gòu)如圖6-9所示。Profile文件夾下面包含兩個(gè)文件:AF.c和AF.h。
AF層提供應(yīng)用支持子層APS到應(yīng)用層的接口,AF層主要提供兩種功能:端點(diǎn)的管理和數(shù)據(jù)的發(fā)送和接收。6.6Profile層分析
圖6-9Profile文件
6.6.1端點(diǎn)的管理
在Zigbee協(xié)議中每個(gè)設(shè)備都被看作一個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都有物理地址(長地址)和網(wǎng)絡(luò)地址(短地址),長地址或短地址用來作為其他節(jié)點(diǎn)發(fā)送數(shù)據(jù)的目的地址。另外,每一個(gè)節(jié)點(diǎn)都有241個(gè)端點(diǎn),其中端點(diǎn)0預(yù)留,端點(diǎn)1~240被應(yīng)用層分配,每個(gè)端點(diǎn)是可尋址的。端點(diǎn)的主要作用可以總結(jié)為以下兩個(gè)方面。
數(shù)據(jù)的發(fā)送和接收:當(dāng)一個(gè)設(shè)備發(fā)送數(shù)據(jù)時(shí),必須指定發(fā)送目的節(jié)點(diǎn)的長地址或短地址以及端點(diǎn)來進(jìn)行數(shù)據(jù)的發(fā)送和接收,并且發(fā)送方和接收方所使用的端點(diǎn)號(hào)必須一致。綁定:如果設(shè)備之間需要綁定,那么在Zigbee的網(wǎng)絡(luò)層必須注冊(cè)一個(gè)或者多個(gè)端點(diǎn)來進(jìn)行數(shù)據(jù)的發(fā)送和接收以及綁定表的建立。
端點(diǎn)的實(shí)現(xiàn)由端點(diǎn)描述符來完成,每一個(gè)端點(diǎn)描述符由一個(gè)結(jié)構(gòu)體來實(shí)現(xiàn),在端點(diǎn)描述符中又包含了一個(gè)簡單描述符,它們的定義在AF.h中,具體講解如下。
1.端點(diǎn)描述符
節(jié)點(diǎn)中的每一個(gè)端點(diǎn)都需要一個(gè)端點(diǎn)描述符,此端點(diǎn)描述符結(jié)構(gòu)體定義在AF.h文件中,如下所示。
【結(jié)構(gòu)體6-1】endPointDesc_t
typedefstruct
{
byteendPoint;
byte*task_id;
SimpleDescriptionFormat_t*simpleDesc;
afNetworkLatencyReq_tlatencyReq;
}endPointDesc_t;
其中,endPointDesc_t結(jié)構(gòu)體中每個(gè)成員所代表的含義如表6-4所示。
表6-4endPointDesc_t結(jié)構(gòu)體成員
2.簡單描述符
每一個(gè)端點(diǎn)必有一個(gè)Zigbee簡單描述符,其他設(shè)備通過查詢這個(gè)端點(diǎn)的簡單描述符來獲得設(shè)備的一些信息,端點(diǎn)的簡單描述符結(jié)構(gòu)體在AF.h文件中定義。
【結(jié)構(gòu)體6-2】SimpleDescriptionFormat_t
typedefstruct
{
byteEndPoint;
uint16AppProfId;
uint16AppDeviceId;
byteAppDevVer:4;
byteReserved:4;
byteAppNumInClusters;
cId_t*pAppInClusterList;
byteAppNumOutClusters;
cId_t*pAppOutClusterList;
}SimpleDescriptionFormat_t;
其中,SimpleDescriptionFormat_t結(jié)構(gòu)體中每個(gè)成員所代表的含義如表6-5所示。
表6-5SimpleDescriptionFormat_t結(jié)構(gòu)體成員含義在實(shí)際數(shù)據(jù)收發(fā)的過程中,參與通信的兩個(gè)設(shè)備之間簡單描述符的輸入/輸出簇要相對(duì)應(yīng),即發(fā)送方的輸出簇對(duì)應(yīng)接收方的輸入簇。例如,在Zstack官方的例程SampleAPP中,發(fā)送方所用的輸入/輸出簇都為SampleApp_ClusterList[],具體如示例6-4所示。
【示例6-4】收發(fā)雙方的輸入/輸出簇
constcId_t
SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS]=
{
SAMPLEAPP_PERIODIC_CLUSTERID,
SAMPLEAPP_FLASH_CLUSTERID
};
3.端點(diǎn)的注冊(cè)
在端點(diǎn)配置成功后,需要在AF層注冊(cè)端點(diǎn),用到的函數(shù)是afRegister(),此函數(shù)在AF.c文件中定義,應(yīng)用層將調(diào)用此函數(shù)注冊(cè)一個(gè)新的端點(diǎn)到AF層,其函數(shù)原型為:
【函數(shù)6-8】afRegister
afStatus_tafRegister(endPointDesc_t*epDesc)。
參數(shù)描述:epDesc—指向端點(diǎn)描述符的指針。
返回值:afStatus_t—如果注冊(cè)成功則返回ZSuccess,否則返回ZcomDef.h中定義的錯(cuò)誤。
6.6.2數(shù)據(jù)的發(fā)送和接收
Zstack協(xié)議棧數(shù)據(jù)的發(fā)送和接收是通過數(shù)據(jù)發(fā)送和接收API來實(shí)現(xiàn)的,數(shù)據(jù)發(fā)送和接收的API在AF層定義。
1.數(shù)據(jù)的發(fā)送
數(shù)據(jù)的發(fā)送只要通過調(diào)用數(shù)據(jù)發(fā)送函數(shù)即可實(shí)現(xiàn),數(shù)據(jù)發(fā)送函數(shù)為AF_DataRequest(),此函數(shù)在AF.c文件中定義,數(shù)據(jù)發(fā)送函數(shù)原型為:
【函數(shù)6-9】AF_DataRequest()
afStatus_tAF_DataRequest
(
afAddrType_t*dstAddr,
endPointDesc_t*srcEP,
uint16cID,
uint16len,
uint8*buf,
uint8*transID,
uint8options,
uint8radius
);
各參數(shù)描述如下:
destAddr:指向發(fā)送目的的地址指針,地址類型為一個(gè)結(jié)構(gòu)體。
srcEP:指向目的端點(diǎn)的端點(diǎn)描述符指針。
cID:發(fā)送端點(diǎn)的輸出簇ID。
len:發(fā)送字節(jié)數(shù)。
buf:指向發(fā)送數(shù)據(jù)緩存的指針。
transID:發(fā)送序列號(hào)指針,如果消息緩存發(fā)送,這個(gè)序列號(hào)將增加1。
options:發(fā)送選項(xiàng),options的詳細(xì)配置如表6-6所示。其中options可以由表6-6中的一項(xiàng)或幾項(xiàng)相或得到。
radius:最大條數(shù)半徑。
表6-6options選項(xiàng)
返回值是一個(gè)afStatus_t類型的數(shù)據(jù),發(fā)送成功將返回“Zsuccess”,發(fā)送失敗將返回ZcomDef.h中定義的“Errors”。
當(dāng)設(shè)備要發(fā)送數(shù)據(jù)時(shí),在應(yīng)用層直接調(diào)用此函數(shù)即可,發(fā)送信息代碼如示例6-5所示。
【示例6-5】發(fā)送信息
voidMySendtest_SendPeriodicMessage(void)
{//發(fā)送的數(shù)據(jù)
chartheMessageData[]="LED1";
if(AF_DataRequest(//發(fā)送目的地址
&MySendtest_Periodic_DstAddr,
//發(fā)送的端點(diǎn)描述符
&MySendtest_epDesc,
//簇ID號(hào)
MySendtest_PERIODIC_CLUSTERID,
//發(fā)送的字節(jié)長度
(uint16)osal_strlen(theMessageData)+1,
//發(fā)送的數(shù)據(jù)
(uint8*)theMessageData,
//發(fā)送的數(shù)據(jù)ID序號(hào)
&MyfirstAppCoordManage_TransID,
//設(shè)置路由發(fā)現(xiàn)
AF_DISCV_ROUTE,
//設(shè)置路由域
AF_DEFAULT_RADIUS)==ZSUCCESS)
{
}
else
{
}
}
2.發(fā)送數(shù)據(jù)的目的地址
發(fā)送函數(shù)AF_DataRequest()中的第一個(gè)參數(shù)是發(fā)送目的地址的信息,目的地址的信息為一個(gè)結(jié)構(gòu)體,此結(jié)構(gòu)體在AF.h中定義。
【結(jié)構(gòu)體6-3】afAddrType_t
typedefstruct
{
union
{
uint16shortAddr;
ZLongAddr_textAddr;
}addr;
afAddrMode_taddrMode;
byteendPoint;
uint16panId;
}afAddrType_t;
其中,結(jié)構(gòu)體afAddrType_t中有四個(gè)成員,每個(gè)成員所代表的含義如表6-7所示。
表6-7afAddrType_t結(jié)構(gòu)體成員其中,addrMode被定義為枚舉類型afAddrMode_t,afAddrMode_t成員定義了發(fā)送信息的四種地址模式,afAddrMode_t在AF.h中定義。
【枚舉6-1】afAddrMode_t
typedefenum
{//間接尋址
afAddrNotPresent=AddrNotPresent,
//單點(diǎn)尋址,指定短地址
afAddr16Bit=Addr16Bit,
//單點(diǎn)尋址,指定長地址
afAddr64Bit=Addr64Bit,
//組尋址
afAddrGroup=AddrGroup,
//廣播尋址
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 文化交流項(xiàng)目作業(yè)管理制度
- 扶貧合作社制度的構(gòu)建與發(fā)展
- 房地產(chǎn)行業(yè)人力資源管理制度優(yōu)化研究
- 信息技術(shù)行業(yè)的科技創(chuàng)新管理制度
- 交通運(yùn)輸工程造價(jià)審核制度
- 護(hù)理質(zhì)量評(píng)價(jià)制度的建立
- 2021學(xué)年某第四小學(xué)班級(jí)管理制度
- 物流行業(yè)供應(yīng)商安全管理新規(guī)制度
- 數(shù)據(jù)收集與分析制度
- 醫(yī)院患者權(quán)益保護(hù)信息公開制度
- AI時(shí)代大學(xué)生創(chuàng)新創(chuàng)業(yè)導(dǎo)航智慧樹知到答案章節(jié)測(cè)試2023年西南大學(xué)
- 臥式罐剩余體積與液位關(guān)系計(jì)算方式-excel
- 公共政策案例分析例文范文(通用9篇)
- 三年級(jí)上冊(cè)道德與法治知識(shí)點(diǎn) 解答題50道 部編版(含答案)
- 富士康公司組織架構(gòu)及部門職責(zé)
- 庫區(qū)倒罐作業(yè)操作規(guī)程
- 二年級(jí)下冊(cè)乘除法口算題
- 中國地圖矢量圖課件
- 新版現(xiàn)代西班牙語第二冊(cè)課后答案
- 熱電廠管理提升專題方案
- 2022年第一學(xué)期田徑社團(tuán)活動(dòng)計(jì)劃
評(píng)論
0/150
提交評(píng)論