《Zigbee開(kāi)發(fā)技術(shù)及實(shí)踐》課件第6章_第1頁(yè)
《Zigbee開(kāi)發(fā)技術(shù)及實(shí)踐》課件第6章_第2頁(yè)
《Zigbee開(kāi)發(fā)技術(shù)及實(shí)踐》課件第6章_第3頁(yè)
《Zigbee開(kāi)發(fā)技術(shù)及實(shí)踐》課件第6章_第4頁(yè)
《Zigbee開(kāi)發(fā)技術(shù)及實(shí)踐》課件第6章_第5頁(yè)
已閱讀5頁(yè),還剩416頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第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ī)制。

掌握Z(yǔ)stack各層的作用。

【描述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)用開(kāi)發(fā)的基礎(chǔ)。6.1概述

Zstack協(xié)議棧符合Zigbee協(xié)議結(jié)構(gòu),由物理層、MAC層、網(wǎng)絡(luò)層和應(yīng)用層組成。如本書(shū)前面所述,物理層和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)容:物理層定義了物理無(wú)線信道和MAC子層之間的接口,提供物理層數(shù)據(jù)服務(wù)單元(PD-SAP)和物理層管理服務(wù)(MLME-SAP)。

MAC(介質(zhì)接入控制子層):MAC層負(fù)責(zé)處理所有物理無(wú)線信道的訪問(wèn),并產(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)加入或者離開(kāi)網(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ù)庫(kù)(即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è)備通過(guò)ZDO請(qǐng)求描述信息,接收到這些請(qǐng)求時(shí),ZDO會(huì)調(diào)用配置對(duì)象獲取相應(yīng)的描述符值。ZDO通過(guò)APSME-SAP接口提供綁定服務(wù)。

6.2.2Zstack協(xié)議棧

Zstack協(xié)議??梢詮腡I的官方網(wǎng)站下載(截止本書(shū)出版時(shí),Zstack協(xié)議棧的最新版本為Zstack-CC2530-2.5.1a),其下載網(wǎng)址為,下載完成后,雙擊可執(zhí)行程序即可安裝。使用IAR8.10版本打開(kāi)Zstack-CC2530-2.5.1a中的SampleApp工程,其協(xié)議棧代碼文件夾如圖6-1所示。

其中部分層的功能如下:

APP:應(yīng)用層目錄,用戶(hù)可以根據(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庫(kù)函數(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è)半開(kāi)源的協(xié)議棧,其中MAC層和ZMAC層的源碼沒(méi)有全部開(kāi)源,關(guān)于他們的具體內(nèi)容,在實(shí)際的工程開(kāi)發(fā)中也不需要詳細(xì)了解。

Zigbee的HAL層提供了開(kāi)發(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ù)來(lái)決定閃爍的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()和詢(xún)檢函數(shù)Hal_ProcessPoll()。

(1)

Hal_Init()函數(shù)是硬件初始化函數(shù),其功能是通過(guò)“注冊(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)用,用來(lái)對(duì)可能產(chǎn)生的硬件事件進(jìn)行詢(xún)檢。函數(shù)原型為:

【函數(shù)6-5】Hal_ProcessPoll()

voidHal_ProcessPoll()

{

//定時(shí)器詢(xún)檢

#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)

HalTimerTick();

#endif

//UART詢(xún)檢

#if(definedHAL_UART)&&(HAL_UART==TRUE)

HalUARTPoll();

#endif

//定時(shí)器詢(xún)檢

#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)

//在Zstack-CC2530-2.5.1a版本中移除了定時(shí)器的初始化,但不影響Zstack的運(yùn)行。

#error"Thehaltimerdrivermoduleisremoved."

#endif

//串口詢(xún)檢

#if(definedHAL_UART)&&(HAL_UART==TRUE)

HalUARTPoll();

#endif

//SPI詢(xún)檢

#if(definedHAL_SPI)&&(HAL_SPI==TRUE)

HalSpiPoll();

#endif

//USB詢(xún)檢(僅限CC2530)

#if(definedHAL_HID)&&(HAL_HID==TRUE)

usbHidProcessEvents();

#endif

//如果定義了休眠模式

#ifdefined(POWER_SAVING)

//允許在下一個(gè)事件到來(lái)之前進(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目錄下頭文件類(lèi)型

6.3.3Target文件夾

Target目錄下包含了某個(gè)設(shè)備類(lèi)型下的硬件驅(qū)動(dòng)文件、硬件開(kāi)發(fā)板上的配置文件、MCU信息和數(shù)據(jù)類(lèi)型。本書(shū)采用的硬件平臺(tái)為CC2530,因此本節(jié)以硬件設(shè)備類(lèi)型CC2530EB(EB是版本號(hào),表示的是評(píng)估版)為例進(jìn)行講解,如圖6-5所示。

注意:上述“CC2530EB”中的字符“EB”是TI公司的Zstack在某個(gè)硬件實(shí)現(xiàn)上的版本號(hào),例如,“BB”是電池版(BatteryBoard),“DB”是開(kāi)發(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文件中可以定義開(kāi)發(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的打開(kāi)和關(guān)閉,其代碼在hal_board_cfg.h文件中,代碼如下:

【代碼6-3】hal_board_cfg.h

/*如果定義了HAL_BOARD_CC2530EB_REV17且沒(méi)有定義HAL_PA_LNA和HAL_PA_LNA_

CC2590,則定義LED的狀態(tài)*/

#ifdefined(HAL_BOARD_CC2530EB_REV17)&&!defined(HAL_PA_LNA)

&&!defined(HAL_PA_LNA_CC2590)

//打開(kāi)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ù)開(kāi)發(fā)板的不同,可以設(shè)置不同的LED,其設(shè)置過(guò)程如上所述。

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ù)用來(lái)控制LED的亮滅,該函數(shù)的原型如下:

【函數(shù)6-6】HalLedSet()

HalLedSet(uint8leds,uint8mode);

其中:

參數(shù)leds,指LED的名稱(chēng),取值可以是:

HAL_LED_1。

HAL_LED_2。

HAL_LED_3。

HAL_LED_4。參數(shù)mode,指LED的狀態(tài),取值可以為以下幾種情況:

打開(kā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ù)是用來(lái)控制LED閃爍的,函數(shù)原型如下:

【函數(shù)6-7】HalLedBlink()

HalLedBlink(uint8leds,uint8numBlinks,uint8percent,uint16period)

其中:

參數(shù)leds,指LED的名稱(chēng),參數(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)地址類(lèi)型的分配、協(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)地址類(lèi)型的選擇

Zstack中地址類(lèi)型有兩種:64位IEEE地址和16位網(wǎng)絡(luò)地址(在Zstack中也稱(chēng)短地址或網(wǎng)絡(luò)短地址)。

64位IEEE地址:即MAC地址(也稱(chēng)“長(zhǎng)地址”或“擴(kuò)展地址”),是一個(gè)全球唯一的地址,一經(jīng)分配將跟隨設(shè)備一生,通常由制造商在設(shè)備出廠或安裝時(shí)設(shè)置,這些地址由IEEE組織來(lái)維護(hù)和分配。

16位網(wǎng)絡(luò)地址:是設(shè)備加入網(wǎng)絡(luò)后,由網(wǎng)絡(luò)中的協(xié)調(diào)器分配給設(shè)備的地址(也稱(chēng)“短地址”),它在網(wǎng)絡(luò)中是唯一的,用來(lái)在網(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)是非開(kāi)源的,在使用的時(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ò)。

另外,開(kāi)發(fā)者為了開(kāi)發(fā)具有特殊性的產(chǎn)品,可以向Zigbee聯(lián)盟申請(qǐng)自定義的模板,在Zstack協(xié)議棧中,開(kāi)發(fā)者申請(qǐng)了兩種自定義模板。

協(xié)議棧模板由一個(gè)ID標(biāo)識(shí)符區(qū)分,此ID標(biāo)識(shí)符可以通過(guò)查詢(xún)?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é)議?!蹦0宄S糜谥悄芗揖拥目刂?。

“ZigbeePRO協(xié)議棧”模板的ID標(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í)符的定義來(lái)看,這兩個(gè)自定義模板分別是為星型網(wǎng)絡(luò)和樹(shù)型網(wǎng)絡(luò)專(zhuān)門(mén)定義的。三種模板的配置在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

//如果沒(méi)有定義ZIGBEEPRO,那么協(xié)議棧為ZIGBEE模板

#defineSTACK_PROFILE_IDHOME_CONTROLS

#endif

6.4.3網(wǎng)絡(luò)參數(shù)配置

網(wǎng)絡(luò)參數(shù)配置包括對(duì)網(wǎng)絡(luò)類(lèi)型參數(shù)、網(wǎng)絡(luò)深度和網(wǎng)絡(luò)中每一級(jí)可以容納的節(jié)點(diǎn)個(gè)數(shù)的配置。

網(wǎng)絡(luò)類(lèi)型即網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu),包括星型網(wǎng)絡(luò)、樹(shù)型網(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……依次類(lèi)推,在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ò)類(lèi)型參數(shù)和網(wǎng)絡(luò)深度的設(shè)置

在Zstack協(xié)議棧中星型網(wǎng)絡(luò)、樹(shù)型網(wǎng)絡(luò)和網(wǎng)狀型網(wǎng)絡(luò)三種網(wǎng)絡(luò)類(lèi)型的定義在nwk_globals.h文件中,其代碼如下:

【代碼6-6】nwk_globals.h—網(wǎng)絡(luò)類(lèi)型的定義

/**********定義網(wǎng)絡(luò)類(lèi)型***********/

//星型網(wǎng)

#defineNWK_MODE_STAR0

//樹(shù)型網(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ò)類(lèi)型和網(wǎng)絡(luò)深度的定義

//如果協(xié)議棧模板為ZigbeePRO模板

#if(STACK_PROFILE_ID==ZIGBEEPRO_PROFILE)

//網(wǎng)絡(luò)的最大深度為20

#defineMAX_NODE_DEPTH 20

//定義網(wǎng)絡(luò)類(lèi)型為網(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ò)類(lèi)型為網(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ò)類(lèi)型為星型網(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ò)類(lèi)型為網(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來(lái)表示,后者用R來(lái)表示,那么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ù)。依次類(lèi)推,元素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)器來(lái)完成的。在網(wǎng)狀型網(wǎng)絡(luò)中,網(wǎng)絡(luò)地址的分配是由協(xié)調(diào)器隨機(jī)地分配的。但是在樹(shù)型網(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ò)地址,則通過(guò)路由器廣播“網(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è)過(guò)程。如果一個(gè)終端設(shè)備發(fā)生了“地址沖突”,它們的父節(jié)點(diǎn)發(fā)送“重新加入”消息至終端設(shè)備,并要求其更改網(wǎng)絡(luò)地址。然后,終端設(shè)備再發(fā)起“設(shè)備聲明”檢測(cè)新的網(wǎng)絡(luò)地址是否沖突。

3.樹(shù)型網(wǎng)絡(luò)中網(wǎng)絡(luò)地址分配的算法

在Zigbee的樹(shù)型網(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è)備類(lèi)型的設(shè)置,如圖6-8所示為T(mén)ools文件。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í),只需要將所需信道的注釋符“//

”去掉,將原來(lái)使用的信道注釋掉。

當(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è)備類(lèi)型配置文件,其功能是將程序編譯成具有協(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)的配置文件,在此文件中既沒(méi)有編譯協(xié)調(diào)器的功能也沒(méi)有編譯路由器的功能,因此,此文件一般不需要配置。

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)都有物理地址(長(zhǎng)地址)和網(wǎng)絡(luò)地址(短地址),長(zhǎng)地址或短地址用來(lái)作為其他節(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)的長(zhǎng)地址或短地址以及端點(diǎn)來(lái)進(jìn)行數(shù)據(jù)的發(fā)送和接收,并且發(fā)送方和接收方所使用的端點(diǎn)號(hào)必須一致。綁定:如果設(shè)備之間需要綁定,那么在Zigbee的網(wǎng)絡(luò)層必須注冊(cè)一個(gè)或者多個(gè)端點(diǎn)來(lái)進(jìn)行數(shù)據(jù)的發(fā)送和接收以及綁定表的建立。

端點(diǎn)的實(shí)現(xiàn)由端點(diǎn)描述符來(lái)完成,每一個(gè)端點(diǎn)描述符由一個(gè)結(jié)構(gòu)體來(lái)實(shí)現(xiàn),在端點(diǎn)描述符中又包含了一個(gè)簡(jiǎn)單描述符,它們的定義在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.簡(jiǎn)單描述符

每一個(gè)端點(diǎn)必有一個(gè)Zigbee簡(jiǎn)單描述符,其他設(shè)備通過(guò)查詢(xún)這個(gè)端點(diǎn)的簡(jiǎn)單描述符來(lái)獲得設(shè)備的一些信息,端點(diǎn)的簡(jiǎ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ā)的過(guò)程中,參與通信的兩個(gè)設(shè)備之間簡(jiǎn)單描述符的輸入/輸出簇要相對(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ā)送和接收是通過(guò)數(shù)據(jù)發(fā)送和接收API來(lái)實(shí)現(xiàn)的,數(shù)據(jù)發(fā)送和接收的API在AF層定義。

1.數(shù)據(jù)的發(fā)送

數(shù)據(jù)的發(fā)送只要通過(guò)調(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ā)送目的的地址指針,地址類(lèi)型為一個(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類(lèi)型的數(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é)長(zhǎng)度

(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被定義為枚舉類(lèi)型afAddrMode_t,afAddrMode_t成員定義了發(fā)送信息的四種地址模式,afAddrMode_t在AF.h中定義。

【枚舉6-1】afAddrMode_t

typedefenum

{//間接尋址

afAddrNotPresent=AddrNotPresent,

//單點(diǎn)尋址,指定短地址

afAddr16Bit=Addr16Bit,

//單點(diǎn)尋址,指定長(zhǎng)地址

afAddr64Bit=Addr64Bit,

//組尋址

afAddrGroup=AddrGroup,

//廣播尋址

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論