




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、2022/7/141無線傳感器網(wǎng)絡講義ZStack開發(fā)入門2022/7/1424.1 ZStack主流程解析2022/7/143ZStack脈理1- 協(xié)議棧從ZMain.c開始執(zhí)行2022/7/144ZStack脈理 (2)協(xié)議棧由OSAL進行任務調(diào)度2022/7/145ZStack脈理 (2)協(xié)議棧由OSAL進行任務調(diào)度OSAL的工作原理:通過tasksEvents指針訪問事件表的每一項,如果有事件發(fā)生,則查找函數(shù)表找到事件處理函數(shù)進行處理,處理完后,繼續(xù)訪問事件表,查看是否有事件發(fā)生,無限循環(huán)。 2022/7/146ZStack脈理 (2)協(xié)議棧由OSAL進行任務調(diào)度2022/7/147Z
2、Stack脈理 (3)用戶加入應用層事件處理程序2022/7/148應用層初始化及事件處理打開應用層主文件如GerericApp.c文件,可以看到兩個比較重要的函數(shù)GenericApp_Init和GenericApp_ProcessEvent。GenericApp_Init是任務的初始化函數(shù),GenericApp_ProcessEvent則負責處理傳遞給此任務的事件。GenericApp_ProcessEvent函數(shù)的主要功能是判斷由參數(shù)傳遞的事件類型,然后執(zhí)行相應的事件處理函數(shù)。2022/7/149應用層初始化及事件處理2022/7/1410任務 事件任務:INIT過程中的taskID ui
3、nt8 taskID = 0; taskID+OSAL的無限循環(huán)中的idx uint8 idx = 0, +idx tasksCnt事件:ZigBee協(xié)議棧使用2個字節(jié),即16個二進制位來表示某個任務的事件列表,因此,可以使用每個二進制位表示其中一個事件。Uint16 events If(tasksEventsidx) 有事 tasksEventsidx = 0; / Clear the Events for this task.events = (tasksArridx)( idx, events );運行事件處理tasksEventsidx |= events; / Add back un
4、processed events to the current task.2022/7/1411事件事件:Uint16 events If(tasksEventsidx) 有事 tasksEventsidx = 0; / Clear the Events for this task.events = (tasksArridx)( idx, events );運行事件處理tasksEventsidx |= events; / Add back unprocessed events to the current task.2022/7/1412事件的數(shù)據(jù)結(jié)構(gòu) tasksEvents2022/7/1
5、413事件處理循環(huán) 茌系統(tǒng)初始化時,將所有任務的事件初始化為0,因此,首先通過tasksEventsidx是否為0來判斷是否有事件發(fā)生,如果有事件發(fā)生了,則跳出循環(huán)。 然后,讀取該事件。 進而,將事件表中該項清零,注意有可能幾個事件同時發(fā)生,這里清零是暫時的,后面會將未處理的事件存放在事件表中。最后,調(diào)用事件處理函數(shù)去處理,為什么是調(diào)用事件處理函數(shù)呢?還記得tasksArr數(shù)組中每個元素的類型嗎?函數(shù)指針!這就是函數(shù)指針的典型應用。執(zhí)行完事件處理函數(shù)后,需要將未處理的事件返回,即事件處理函數(shù)的返回值保存了未處理的事件,將該事件再寫入事件表中,以便于下次進行處理。2022/7/1414事件處理函
6、數(shù)對事件數(shù)據(jù)結(jié)構(gòu)的處理 GenericApp_ProcessEvent函數(shù)的基本實現(xiàn)方法是:使用osal_msg_receive函數(shù)從消息隊列上接收一個消息(在該消息中包含了事件以及接收到的數(shù)據(jù)),然后使用switch-case話句判斷事件類型,如果是接收到新數(shù)據(jù)事件AF INCOMING_ MSGCMD,則調(diào)用相應的事件處理函數(shù)。注意GenericApp_ProcessEvent最后的return語句,使用了異或運算,可以通過下面的例子看到異或運算的作用。假設同時發(fā)生了串口接收事件和讀取溫度事件,則此時events=Ob00000101,即Ox05,假設現(xiàn)在處理完串口接收事件,則應該將第0位
7、清零,如何實現(xiàn)呢?只需要使用異或運算即可,即enentsOxOl=Ox50 x0l=0 x04,即Ob00000100,可見使用異或運算恰好可以將處理完的事件清除,僅留下未處理的事件。2022/7/1415 從上述函數(shù)中可以看到SYS_EVENT_MSG, SYS_EVENT_MSG與AFINCOMING_MSG_CMD有什么內(nèi)在聯(lián)系呢? 前文講到可以使用每個二進制位表示一個事件,因此在ZigBee協(xié)議棧中,用戶可以自己定義事件,但是,協(xié)議棧同時也給出了幾個已經(jīng)定義好的事件, SYS_EVENT_MSG就是其中的一個事件,SYS_EVENT_MSG的定義如下: #define SYS_EVEN
8、T_ MSG Ox80002022/7/1416由協(xié)議棧定義的事件成為系統(tǒng)強制事件(Mandatory Events),SYS_EVENT_MSG是一個事件集合,主要包括以下幾個事件(其中前兩個較為常用): AF_INCOMING_MSG_CMD 表示收到了一個新的無線數(shù)據(jù)。 ZDO_STATE_CHANGE 當網(wǎng)絡狀態(tài)發(fā)生變化時,會產(chǎn)生該事件,如終端節(jié)點加入網(wǎng)絡。 ZDO_CB_MSG指示每一個注冊的ZDO響應消息。 AF_DATA_CONFIRM_CMD 調(diào)用AF_DataRequest0發(fā)送數(shù)據(jù)時,有時需要確認信息,該事件與此有關。2022/7/1417OSAL的運行機理總結(jié)通過不斷地查
9、詢事件表來判斷是否有事件發(fā)生,如果有事件發(fā)生,則查找函數(shù)表找到對應的事件處理函數(shù)對事件進行處理。事件表使用數(shù)組來實現(xiàn),數(shù)組的每一項對應一個任務的事件,每一位表示一個事件;函數(shù)表使用函數(shù)指針數(shù)組來實現(xiàn),數(shù)組的每一項是一個函數(shù)指針,指向了事件處理函數(shù)。2022/7/1418事件的類型在comdef.h文件中/* * Global System Events */#define SYS_EVENT_MSG 0 x8000 / A message is waiting event (全局事件)#define KEY_CHANGE 0 xC0 / Key Events (子事件)在GenericApp.
10、h中/ Application Events (OSAL) - These are bit weighted definitions.#define GENERICAPP_SEND_MSG_EVT 0 x0001 (自定義全局事件)2022/7/1419消息與事件的區(qū)別 事件是驅(qū)動任務去執(zhí)行某些操作的條件,當系統(tǒng)中產(chǎn)生了一個事件,OSAL將這個事件傳遞給相應的任務后,任務才能執(zhí)行一個相應的操作(調(diào)用事件處理函數(shù)去處理)。通常某些事件發(fā)生時,又伴隨著一些附加信息的產(chǎn)生,例如:從天線接收到數(shù)據(jù)后,會產(chǎn)生AF_INCOMING_MSG_CMD消息,但是任務的事件處理函數(shù)在處理這個事件的時候,還需要得
11、到所收到的數(shù)據(jù)。因此,這就需要將事件和數(shù)據(jù)封裝成一個消息,將消息發(fā)送到消息隊列,然后在事件處理函數(shù)中就可以使用osal_msg_receive,從消息隊列中得到該消息。 MSGpkt= (afIncomingMSGPacket_t *)osal_msg_receive (GenericApp_ TaskID);2022/7/1420消息隊列OSAL維護了一個消息隊列,每一個消息都會被放到這個消息隊列中去,當任務接收到事件后,可以從消息隊列中獲取屬于自己的消息,然后調(diào)用消息處理函數(shù)進行相應的處理即可。 每個消息都包含一個消息頭osal_msg_hdr_t和用戶自定義的消息,osal_msg_hd
12、r_t結(jié)構(gòu)體的定義為: typedef struct void tnext; uint16 len; uint8 dest_id; ) osal msg_hdr_t;2022/7/1421消息中攜帶的事件typedef struct uint8 event; uint8 status; osal_event_hdr_t;2022/7/1422消息中攜帶的子類事件2022/7/1423總結(jié) 如何在應用程序中添加一個新任務在GenericApp.c文件,存在數(shù)組tasksArr和函數(shù)osalInitTasks。tasksArr數(shù)組里存放了所有任務的事件處理函數(shù)的地址;osalInitTasks是O
13、SAL的任務初始化函數(shù),所有任務的初始化工作都在這里面完成,并且自動給每個任務分配一個ID。因此,要添加新任務,只需要編寫兩個函數(shù): 新任務的初始化函數(shù); 新任務的事件處理函數(shù)。 將新任務的初始化函數(shù)添加在osalInitTasks函數(shù)的最后,如下代碼所示。 const pTaskEventHandlerFn tasksArr = macEventLoop, nwk一event_loop, HalProcessEvent, #if defined( MT_TASK) MTProcessEvent. #endif2022/7/1424總結(jié) 如何在應用程序中添加一個新任務 APSevent_loo
14、p, #if defined (ZIGBEEFRAGMENTATION) APSF- ProcessEvent, #endif Z DApp_event_loop, #if defined (ZIGBEE_FREQAGILITY) l I defined (ZIGBEEPANID CONFlICT 1 Z DNwkMgr_event_loop, #endif GenericApp_ProcessEvent );2022/7/1425總結(jié) 如何在應用程序中添加一個新任務 將事件處理函數(shù)的地址加入tasksArr數(shù)組,如下代碼所示。 void osalInitTasks( void) uint8
15、taskID=O: tasksEvents=(uint16*)osal_mem_alloc( sizeof(uint16) *tasksCnt); osal_memset( tasksEvents, O, (sizeof( uint16), *tasksCnt); macTasklnit( taskID+ ); nwk_init(taskID+); Hal_lnit(taskID+); #if defined( MT_TASK) MT_Tasklnit( taskID+ )j #endif APS_Init(taskID+); ZDApp_lnit( taskID+ )j GenericApp
16、_lnit( taskID); 2022/7/1426總結(jié) 如何在應用程序中添加一個新任務在此例中,將此前提到過的GenericApp_ProcessEvent函數(shù)添加到了數(shù)組的末尾,GenericApp_lnit函數(shù)在osalInitTasks中被調(diào)用。需要注意兩點:tasskArr數(shù)組里各事件處理函數(shù)的排列順序要與osalInitTasks函數(shù)中調(diào)用各任務初始化函數(shù)的順序保持一致,只有這樣才能夠保證每個任務的事件處理函數(shù)能夠接收到正確的任務ID(在osalInitTasks函數(shù)中分配)。為了保存osalInitTasks函數(shù)所分配的任務ID,需要給每一個任務定義一個全局變量。如在Gener
17、icApp.c中定義了一個全局變量byte GenericApp_TaskID; 并且在GenericApp_Init函數(shù)中進行了賦值。2022/7/14274.2 ZigBee點到點通訊程序設計2022/7/1428應用需求 開發(fā)一個簡單的點對點通信程序:從發(fā)送端發(fā)送一個數(shù)據(jù),接收端接收到數(shù)據(jù)后校驗收到的數(shù)據(jù)是否正確,并給出相應的指示。 2022/7/1429需求細化ZigBee節(jié)點1配置為一個協(xié)調(diào)器,負責ZigBee網(wǎng)絡的組建。ZigBee節(jié)點2配置為一個終端節(jié)點,上電后加入ZigBee節(jié)點1建立的網(wǎng)絡,然后發(fā)送“LED”給節(jié)點1。 ZigBee節(jié)點1收到數(shù)據(jù)后,對接收到的數(shù)據(jù)進行判斷,如
18、果收到的數(shù)據(jù)是“LED”,則使開發(fā)板上的LED燈閃爍。2022/7/1430配置管理需要開發(fā)兩個程序,一個給協(xié)調(diào)器用,一個給終端節(jié)點用。但一般合在一個工程里,復用公共的文件,而不同的文件采用編譯踢除(Exclude from build)方法處理,并且采用不同的配置。文件呈灰白顯示狀態(tài)說明該文件不參與編譯,ZigBee協(xié)議棧正是使用這種方式實現(xiàn)對源文件編譯的控制。2022/7/1431Exclude from build2022/7/1432配置文件f8w2530.xcl、f8wConfig.cfg、f8wCoord.cfg(或f8wRouter.cfg或f8wEndev.cfg)三個文件包含
19、了節(jié)點的配置信息,具體功能如下:f8w2530.xcl-包含了CC2530單片機的鏈接控制指令(如定義堆棧大小、內(nèi)存分配等),一般不需要改動。 例如:下列代碼定義了外部存儲器的起始地址和結(jié)束地址。 -D_XDATA_START=0 x0001 -D_XDATA_END=0 x1EFFf8wCoord.cfg - 定義了設備類型協(xié)調(diào)器。 -DZDO_COORDINATOR -DRTR_NWKf8wRouter.cfg - 定義了設備類型路由器。 -DRTR_NWKf8wEndev.cfg - 定義了設備類型終端節(jié)點,不含RTR_NWK定義2022/7/1433f8wConfig.cfg包含了信道
20、選擇、網(wǎng)絡號等有關的鏈接命令。例如:下列代碼定義了建立網(wǎng)絡的信道默認為11,即從11信道上建立ZigBee無線網(wǎng)絡,第2行定義了ZigBee無線網(wǎng)絡的網(wǎng)絡號。 -DDEFAULT_CHANLIST=0 x00000800 / 11 - 0 x0B -DZDAPP_CONFIG_PAN_ID=0 xFFFF /16 bit因此,如果想從其他信道上建立ZigBee網(wǎng)絡和修改網(wǎng)絡號,就可以在此修改。 每個設備都有一組能被配置的參數(shù),整個配置參數(shù)在代碼中已經(jīng)定義了默認值(在f8wConfig. cfg中)。在同一個網(wǎng)絡中,所有設備的“網(wǎng)絡細節(jié)”配置參數(shù)(如PANID、Channel等)應該被設置成一樣
21、的值。每個設備的“設備細節(jié)”配置參數(shù)(Coordinator、Router、EndDevice等)可以配置為不同的值。 配置文件2022/7/1434配置文件協(xié)調(diào)器設備將建立網(wǎng)絡,其他設備將發(fā)現(xiàn)和加入這個網(wǎng)絡。 協(xié)調(diào)器將掃描所有被DEFAULT_CHANLIST參數(shù)制定的通道,選擇1個最小能量的通道。如:當DEFAULT_CHANLIST=0 x00003800時,會有多個選擇:11,12,13協(xié)調(diào)器將選擇用ZDAPP_CONFIG_PAN_ID參數(shù)指定的網(wǎng)絡ID。路由器和終端設備將掃描用DEFAULT_CHANLIST配置參數(shù)指定的通道和試圖發(fā)現(xiàn)ID為ZDAPP_CONFIG_PAN_ID參
22、數(shù)指定的網(wǎng)絡。2022/7/1435建立工程-新建文件復制一個已有的范例工程如GenericApp工程,將范例工程中的用戶自定義應用層主文件和頭文件刪除,如GenericApp工程中的GenericApp.h, GenericApp.c新建自己的應用層主文件和頭文件加入工程,如Coordinator.h、Coordinator.c和Enddevice.c 在不同的設備配置中用Exclude from build踢除不需要的文件,下一步,開始編寫代碼。2022/7/1436用戶應用層頭文件在Coordinator.h文件中輸入以下代碼:#ifndef COORDINATOR_H#define C
23、OORDINATOR_H#include ZComDef . h#define GENERICAPP ENDPOINT 10#define GENERICAPP PROFID 0 x0F04#define GENERICAPP DEVICEID 0 x0001#define GENERICAPP DEVICE_VERSION 0#define GENERICAPP_FLAGS 0#define GENERICAPP_MAX CLUSTERS 1#define GENERICAPP CIUSTERID 1extern void GenericApp_lnit( byte task_id );ex
24、tern UINT16 GenericApp_ProcessEvent ( byte task_id. UINT16 events ) ;#endif/* Data Types */typedef uint8 byte;typedef uint16 UINT16;typedef int16 INT16;2022/7/1437用戶應用層主文件 在Coordinator.c中輸入以下代碼: l #include OSAL.h 2 #include AF.h 3 #include ZDApp.h 4 #include ZDObject.h 5 #include ZDProfile.h 6 #incl
25、ude 7 #include Coordinator.h 8 #include DebugTrace.h 9 #if ! defined ( WIN32) 10 #include OnBoard.h 11 #endif 12 #include hal_lcd.h 13 #include hal_led.h 14 #include hal_key.h 15 #include hal_uart.h2022/7/1438用戶應用層主文件 16 const cId_t GenericApp_ClusterListGENERICAPP_ MAX CLUSTERS = 17 GENERICAPP_CLUS
26、TERID 上述代碼中的GENERICAPP_ MAX_CLUSTERS是在Coordinator.h文件中定義的宏,這主要是為了跟協(xié)議棧里面數(shù)據(jù)的定義格式保持一致,下面代碼中的常量都是以宏定義的形式實現(xiàn)的。18 const SimpleDescriptionFormat t GenericApp_SimpleDesc = 1 9 GENERICAPP_ENDPOINT ,2 0 GENERICAPP_PROFID,21 GENERICAPP_DEVICEID2 2 GENERICAPP_DEVICE_VERS ION,2 3 GENERICAPP_FLAGS,24 GENERICAPP_MA
27、X_CLUSTERS,2 5 ( cId_t *) GenericApp_ClusterList, 26 0, 27 (cId_t *)NULL ;上述數(shù)據(jù)結(jié)構(gòu)可以用來描述一個ZigBee設備節(jié)點,稱為簡單設備描述符 2022/7/1439用戶應用層主文件 28 endPointDesc_t GenericApp_epDesc; 29 byte GenericApp_TaskID; 30 byte GenericApp_TransID; 上述代碼定義了三個變量,一個是節(jié)點描述符GenericApp_epDesc,一個是任務優(yōu)先級GenericApp_TaskID,最后一個是數(shù)據(jù)發(fā)送序列號Gen
28、ericApp_TransID。上述代碼中endPointDesc_t結(jié)構(gòu)體(注意,ZigBee協(xié)議棧中新定義的類型一般以_t結(jié)尾)的定義較為復雜,下面是該結(jié)構(gòu)體的定義:typedef struct byte endPoint; byte *task_id; SimpleDescriptionFormat_t *simpleDesc; afNetworkLatencyReq_t latencyReq; endPointDesc_t;2022/7/1440用戶應用層主文件31 void GenericApp_MessageMSGCB( afIncomingMSGPacket_t*pckt );3
29、2 void GenericApp_SendTheMessage( void); 上述代碼聲明了兩個函數(shù),一個是消息處理函數(shù)GenericApp_MessageMSGCB, 另一個是數(shù)據(jù)發(fā)送函數(shù)GenericApp_SendTheMessage。下面是該任務的任務初始化函數(shù),格式較為固定。33 void GenericApp_lnit( byte task_id) 34 GenericApp_TaskID = task_id; /初始化了任務優(yōu)先級(OSAL分配)35 GenericApp_TransID = 0; /將發(fā)送數(shù)據(jù)包的序號初始化為036 GenericApp_epDesc.end
30、Point = GENERICAPP_ENDPOINT;37 GenericApp_epDesc.task_id = &GenericApp_TaskID;38 GenericApp_epDesc.simpleDesc = hdr.event ) case AF_INCOMING_MSG_CMD:48 GenericApp_MessageMSGCB ( MSGpkt ) ;/接收到了無線數(shù)據(jù),進行處理。 49 break;50 default :51 break; / end of switch52 osal_msg_deallocate( (uint8 *)MSGpkt );/釋放消息所占據(jù)
31、的存儲空間,堆 53 MSGpkt= (afIncomingMSGPacket_t *).osal_msg_receive(GenericApp_TaskID); /end of while54 return (events SYS_EVENT_MSG) ; / end of if55 return 0; / end of function消息處理函數(shù)大部分代碼是固定的,主體不需要修改,只需特定事件的處理邏輯2022/7/1442用戶應用層主文件56 void GenericApp_MessageMSGCB( afIncomingMSGPacket_ttpkt) 57 unsigned cha
32、r buffer4 =” ”;58 switch (pkt-clusterId) 59 case GENERICAPP_CLUSTERID :60 osal_memcpy (buffer, pkt-cmd.Data, 3) ;61 if (buffer0=L)|(buffer1= E) | (buffer2=”D”) 62 HalLedBlink (HAL_LED_2, 0, 50, 500);63 else 64 HalLedSet ( HAL_LED_2 , HAL_LED MODE_ON) ; 65 break; 上述代碼中,字體加粗部分的格式是固定的,實現(xiàn)的基本功能如下: 第60行,將
33、收到的數(shù)據(jù)拷貝到緩沖區(qū)buffer中。 第61行,判斷接收到的數(shù)據(jù)是不是“LED”三個字符,如果是這三個字符,則執(zhí)行第62行,使LED2閃爍,如果接收到的不是這三個字符,則點亮LED2即可。2022/7/1443終端節(jié)點編程 用戶應用層主文件頭文件與協(xié)調(diào)器一樣,主文件大部分也一樣,只需修改應用層事件處理函數(shù):43 UINT16 GenericApp_ProcessEvent ( byte task_id, UINT16 events afIncomingMSGPacket_t *MSGpkt;44 if ( events & SYS EVENT_MSG ) 45 MSGpkt = (afInc
34、omingMSGPacket_t *) osal_msg_receive ( GenericApp_TaskID ) ;46 while ( MSGpkt ) / loop MSGpkt47 switch ( MSGpkt-hdr.event ) 48 case ZDO_STATE_CHANGE :49 GenericApp_NwkState = (devStates_t) (MSGpkt-hdr.status) ;/讀取節(jié)點的設備類型50 if (GenericApp_NwkState = DEV_END_DEVICE) /如果是終端節(jié)點51 GenericApp_SendTheMessag
35、e ( ); /實現(xiàn)無線數(shù)據(jù)發(fā)送。 52 break;53 default :54 break; osal_msg_deallocate (uint8 *) MSGpkt) ;55 MSGpkt=(afIncomingMSGPacket_t *) osal_msg_receive(GenericApp_TaskID ) ; / loop MSGpkt56 return (events SYS_EVENT_MSG); 57 return 0; 2022/7/1444終端節(jié)點編程 用戶應用層主文件數(shù)據(jù)發(fā)送函數(shù)的實現(xiàn):58 void GenericApp_SendTheMessage( void)
36、59 unsigned char theMessageData4 = “LED”;/存放要發(fā)送的數(shù)據(jù)6 0 afAddrType_t my_DstAddr; / 目的節(jié)點+EP61 my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; /將發(fā)送地址模式設置為單播62 my_DstAddr. endPoint = GENERICAPP_ENDPOINT; /初始化端口號 63 my_DstAddr. addr. shortAddr = 0 x0000; /向協(xié)調(diào)器發(fā)送 64 AF_DataRequest( &my_DstAddr, &GenericApp_
37、epDesc, GENERICAPPCLUSTERID, 3, theMessageData, &GenericApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS);65 HalLedBlink( HAL_lED_2,0,50,500); 2022/7/1445終端節(jié)點編程 用戶應用層主文件數(shù)據(jù)發(fā)送目的地址類型afAddrType_t ,該地址格式主要用在數(shù)據(jù)發(fā)送函教中。 typedef struct union uint16 shortAddr; ZlongAddr_t extAddr; addr; afAddrMode_t addrMode; by
38、te endPoint; uint16 panId; a fAddrType_t; 在ZigBee網(wǎng)絡中,要向某個節(jié)點發(fā)送數(shù)據(jù),需要從以下兩方面來考慮。 使用何種地址格式標識該節(jié)點的位置使用一種地址格式來標識該節(jié)點,因為每個節(jié)點都有自己的網(wǎng)絡地址,所以可以使用網(wǎng)絡地址來標識該節(jié)點,因此,afAddrType_t結(jié)構(gòu)體中定義了用于標識該節(jié)點網(wǎng)絡地址的變量uint16 shortAddr。 以何種方式向該節(jié)點發(fā)送數(shù)據(jù) 向節(jié)點發(fā)送數(shù)據(jù)可以采用單播、廣播和多播的方式,在發(fā)送數(shù)據(jù)前需要定義好具體采用哪種模式發(fā)送,因此,afAddrType_t結(jié)構(gòu)體中定義了用于標識發(fā)送數(shù)據(jù)方式的變量afAddrMode_
39、t addrMode。2022/7/1446終端節(jié)點編程 數(shù)據(jù)發(fā)送函數(shù)在ZigBee協(xié)議棧中進行數(shù)據(jù)發(fā)送可以調(diào)用AF_ DataRequest函數(shù)實現(xiàn),該函數(shù)會調(diào)用協(xié)議棧里面與硬件相關的函數(shù)最終將數(shù)據(jù)通過天線發(fā)送出去,這里面涉及對射頻模塊的操作,例如:打開發(fā)射機,調(diào)整發(fā)射機的發(fā)送功率等內(nèi)容,這些部分協(xié)議棧已經(jīng)實現(xiàn)了,用戶不需自己寫代碼去實現(xiàn),只需要掌握AF DataRequest函數(shù)的使用方法即可。 afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,uint16 cID,uint16 len,uint
40、8 *buf,uint8 *transID,uint8 options,uint8 radius )2022/7/1447終端節(jié)點編程 數(shù)據(jù)發(fā)送函數(shù) uint16 cID 該參數(shù)描述的是命令號,在ZigBee協(xié)議里的命令主要用來標識不同的控制操作,不同的命令號代表了不同的控制命令,如節(jié)點1的端口1可以給節(jié)點2的端口1發(fā)送控制命令,當該命令的ID為1時表示點亮LED,當該命令的ID為0時表示熄滅LED,因此,該參數(shù)主要是為了區(qū)別不同的命令。如終端節(jié)點在發(fā)送數(shù)據(jù)時使用的命令ID是GENERICAPP_ CLUSTERID,該宏定義是在Coordinator.h文件中定義的,它的值為1。uint16
41、 len - 該參數(shù)標識了發(fā)送數(shù)據(jù)的長度。uint8 *buf-該參數(shù)是指向發(fā)送數(shù)據(jù)緩沖區(qū)的指針,發(fā)送數(shù)據(jù)時只需要將所要發(fā)送的數(shù)據(jù)緩沖區(qū)的地址傳遞給該參數(shù)即可,數(shù)據(jù)發(fā)送函數(shù)會從該地址開始按照指定的數(shù)據(jù)長度取得發(fā)送數(shù)據(jù)進行發(fā)送。uint8 *transID - 該參數(shù)是一個指向發(fā)送序號的指針,每次發(fā)送數(shù)據(jù)時,發(fā)送序號會自動加1(協(xié)議棧里面實現(xiàn)的該功能),在接收端可以通過發(fā)送序弓來判斷是否丟包,同時可以計算出丟包率。uint8 Options和uint8 radius-這兩個參數(shù)取默認值即可,options參數(shù)可以取AF_DISCV_ ROUTE,radius參數(shù)可以取AF_DEFAULT_ RA
42、DIUS。 2022/7/1448ZigBee協(xié)議術(shù)語設備(device) :一般來說,一個節(jié)點( FFD/RFD)就是一個設備,對應于一個無線單片機,如CC2530;一個設備有一個無線射頻端,具有唯一的IEEE地址和網(wǎng)絡地址。端點( endpoint) :它是一個8位的字段,描述一個射頻端所支持的不同應用。每一個ZigBee節(jié)點可以包含多個端點。端點0 x00用于尋址設備配置對象這是每個ZigBee設備都必須使用的端點。端點0 xff用來尋址所有活動端點,而端點0 xfl0 xfe暫時預留。因此,一個物理ZigBee射頻端在端點0 x010 xf0上共支持240個應用,即一個物理信道中最多可
43、能有240條虛擬信道。2022/7/1449ZigBee協(xié)議術(shù)語(續(xù)) 一個典型的ZigBee節(jié)點也將有很多屬性(attribute) ,每個屬性都有自己的值。一個簇(cluster)實際上是一些相關命令和屬性的集合,這些命令和屬性一起被定義為一個應用接口,在整個網(wǎng)絡中,每個簇都被分配了一個唯一的簇ID。 ZigBee協(xié)議還定義了一個稱為規(guī)范(profile)的術(shù)語,規(guī)范是指對分布式應用的描述,它是對邏輯設備及其接口描述的集合,是面向某個具體應用類別的公約、準則。它在消息、消息格式、請求數(shù)據(jù)或請求創(chuàng)建一個共同的分布式應用程序的處理行為上達成了共識。這意味著在ZigBee標準的范圍內(nèi),各個廠商共
44、同合作形成統(tǒng)一的技術(shù)解決方案。例如:ZigBee聯(lián)盟制定的家庭照明控制燈的規(guī)范就希望不同的燈光設備供應商能夠統(tǒng)一不同的電燈類型和控制類型。 2022/7/14504.3 簡單通訊的擴展1 協(xié)調(diào)器串口輸出2022/7/1451串口的作用串口是開發(fā)板和用戶電腦交互的一種工具,正確地使用串口對于ZigBee無線網(wǎng)絡的學習具有較大的促進作用。 串口的作用體現(xiàn)在兩個方面:調(diào)試打印輸出ZigBee無線網(wǎng)絡與計算機間的傳輸通道在前面的ZigBee簡單無線通訊應用中,協(xié)調(diào)器收到數(shù)據(jù)包后在程序內(nèi)部進行檢查,判斷是否正確,通過LED的顯示模式來表征正確與否,不夠靈活。下面我們擴展協(xié)調(diào)器的功能,讓其收到數(shù)據(jù)后通過串
45、口輸出到PC中讓串口調(diào)試助手直接顯示收到的數(shù)據(jù)內(nèi)容。2022/7/1452ZStack中的串口使用嵌入式開發(fā)中使用串口的基本步驟: 初始化串口,包括設置波特率、中斷等; 向發(fā)送緩沖區(qū)發(fā)送數(shù)據(jù)或者從接收緩沖區(qū)讀取數(shù)據(jù)。但是由于ZigBee協(xié)議棧的存在,使得串口的使用略有不同,在ZigBee協(xié)議棧中已經(jīng)對串口初始化所需要的函數(shù)進行了實現(xiàn),用戶只需要傳遞幾個參數(shù)就可以使用串口,此外,ZigBee協(xié)議棧還實現(xiàn)了串口的讀取函數(shù)和寫入函數(shù)。因此,用戶在使用串口時,只需要掌握ZigBee協(xié)議棧提供的串口操作相關的三個函數(shù)即可。ZigBee協(xié)議棧中提供的與串口操作有關的三個函數(shù)為:uint8 HalUARTO
46、pen(uint8 port, halUARTCfg_t *config);uint16 HaIUARTRead(uint8 port, uint8 *buf, uint16 len);uint16 HaIUARTWrite(uint8 port,uint8 *buf, uint16 len).2022/7/1453協(xié)調(diào)器串口輸出編程思路首先確保主文件中包含了串口頭文件#include “hal_uart.h”其次為串口消息緩存設置緩沖區(qū)然后在初始化部分增加串口初始化代碼最后在無線數(shù)據(jù)包接收函數(shù)中增加串口輸出代碼2022/7/1454協(xié)調(diào)器代碼修改 在Coordinator.c中輸入以下代碼:
47、 l #include OSAL.h 2 #include AF.h 3 #include ZDApp.h 4 #include ZDObject.h 5 #include ZDProfile.h 6 #include 7 #include Coordinator.h 8 #include DebugTrace.h 9 #if ! defined ( WIN32) 10 #include OnBoard.h 11 #endif 12 #include hal_lcd.h 13 #include hal_led.h 14 #include hal_key.h 15 #include hal_ua
48、rt.h2022/7/1455協(xié)調(diào)器代碼修改16 const cId_t GenericApp_ClusterListGENERICAPP_ MAX CLUSTERS =17 GENERICAPP_CLUSTERID 18 const SimpleDescriptionFormat t GenericApp_SimpleDesc = 19 GENERICAPP_ENDPOINT ,20 GENERICAPP_PROFID,21 GENERICAPP_DEVICEID22 GENERICAPP_DEVICE_VERS ION,23 GENERICAPP_FLAGS,24 GENERICAPP_M
49、AX_CLUSTERS,25 ( cId_t *) GenericApp_ClusterList,26 0,27 (cId_t *)NULL ;28 endPointDesc_t GenericApp_epDesc;29 byte GenericApp_TaskID;30 byte GenericApp_TransID;31 unsigned char uartbuf 128;/串口消息緩存32 void GenericApp_MessageMSGCB ( afIncomingMSGPacket_t *pckt ) ;33 void GenericApp_SendTheMessage ( vo
50、id ) ;34 static void rxCB (uint8 port,uint8 event); /串口接收處理函數(shù) 2022/7/1456協(xié)調(diào)器代碼修改void GenericApp_lnit ( byte task_id ) halUARTCfg_t uartConfig; GenericApp_TaskID = task_id; GenericApp_TransID = 0; GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT; GenericApp_epDesctask_id = &GenericApp_TaskID; Generic
51、App_epDesc.simpleDesc = (SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc; GenericApp_epDesc.latencyReq = noLatencyReqs; afRegister( &GenericApp_epDesc);1 uartConfig.configured = TRUE ;2 uartConfig.baudRate = HAL_UART_BR_115200;3 uartConfig.flowControl = FALSE;4 uartConfig.callBackFunc = rxCB;/注冊串口
52、接收處理函數(shù)5 HalUARTOpen(0,&uartConfig);2022/7/1457halUARTCfg_ttypedef struct bool configured; uint8 baudRate; bool flowControl; uint16 flowControlThreshold; uint8 idleTimeout; halUARTBufControl_t rx; halUARTBufControl_t tx; bool intEnable; uint32 rxChRvdTime; halUARTCBack_t callBackFunc;halUARTCfg_t;/*
53、fn HalUARTOpen* brief Open a port according tp the configuration specified by parameter.* param port - UART port* config - contains configuration information*/uint8 HalUARTOpen(uint8 port, halUARTCfg_t *config)2022/7/1458協(xié)調(diào)器代碼修改41 UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events ) 42 afIn
54、comingMSGPacket t *MSGpkt;43 if ( events & SYS_EVENT_MSG ) 44 MSGpkt = (afIncomingMSGPacket_t *) osal_msg_receive(GenericApp_TaskID) ;45 while ( MSGpkt ) 46 switch ( MSGpkt-hdr.event ) case AF_INCOMING_MSG_CMD:48 GenericApp_MessageMSGCB ( MSGpkt ) ;/接收到了無線數(shù)據(jù),進行處理。 49 break;50 default :51 break; / en
55、d of switch52 osal_msg_deallocate( (uint8 *)MSGpkt );/釋放消息所占據(jù)的存儲空間,堆 53 MSGpkt= (afIncomingMSGPacket_t *).osal_msg_receive(GenericApp_TaskID); /end of while54 return (events SYS_EVENT_MSG) ; / end of if55 return 0; / end of function2022/7/1459協(xié)調(diào)器代碼修改56 void GenericApp_MessageMSGCB( afIncomingMSGPack
56、et_ttpkt) 57 unsigned char buffer4 =” ”;58 switch (pkt-clusterId) 59 case GENERICAPP_CLUSTERID :60 osal_memcpy (buffer, pkt-cmd.Data, 3) ;61 if (buffer0=L)|(buffer1= E) | (buffer2=”D”) 62 HalLedBlink (HAL_LED_2, 0, 50, 500);63 else 64 HalLedSet ( HAL_LED_2 , HAL_LED MODE_ON) ; /通過串口發(fā)送接收到的無線數(shù)據(jù)包 HalUA
57、RTWrite( SERIAL_APP_PORT, pkt-cmd.Data, pkt-cmd.DataLength );65 break; 2022/7/1460串口接收 static void rxCB(uint8 port,uint8 event) 1 HalUARTRead(0,uartbuf,16) ;2 if (osal.memcmp (uartbuf, ,16)3 4 HalUARTWrite(0,uartbuf, 16) ;5 第1行,調(diào)用HaIUARTRead()函數(shù),從串口讀取數(shù)據(jù)并將其存放在uartbuf數(shù)組中。第2行,使用osal_memcmp0函數(shù)判斷接收到的數(shù)據(jù)是否
58、是字符串“www. ”,如果是該字符串,在osal_memcmp0函數(shù)返回TURE,執(zhí)行第4行。2022/7/1461條件編譯選項2022/7/14624.4簡單通訊的擴展2 終端節(jié)點周期發(fā)送2022/7/1463周期發(fā)送需求和方法上述簡單無線通信中,終端節(jié)點只在加入網(wǎng)絡后發(fā)了一個數(shù)據(jù)包,而實際應用中常常需要每隔一段時間采集一個傳感器數(shù)據(jù)并發(fā)送出去,因此,需要做周期發(fā)送的代碼編程。怎么實現(xiàn)周期性的發(fā)送數(shù)據(jù)呢?使用ZigBee協(xié)議棧里面的一個定時函數(shù)osal_start_timerEx(),該函數(shù)可以實現(xiàn)毫秒級的定時,定時時間到達后發(fā)送數(shù)據(jù)到協(xié)調(diào)器,發(fā)送完數(shù)據(jù)后,再定時一段時間,定時時間到達后,
59、發(fā)送數(shù)據(jù)到協(xié)調(diào)器,這樣就實現(xiàn)了數(shù)據(jù)的周期性發(fā)送。2022/7/1464osal start_timerEx()函數(shù) 函數(shù)原型如下: uint8 osal start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value ), 有三個參數(shù):uint8 taskID -該參數(shù)表明定時時間到達后,哪個任務對其作出響應;uint16 event_id-該參數(shù)是一個事件ID,定時時間到達后,該事件發(fā)生,因此需要添加一個新的事件,該事件發(fā)生則表明定時時間到達,因此可以在該事件的事件處理函數(shù)中實現(xiàn)數(shù)據(jù)發(fā)送;uint16 timeout_va
60、lue -定時時間由timeout_value(以毫秒為單位)參數(shù)確定。添加新事件的方法是:在Enddevice.c文件中添加如下宏定義。#define SEND_DATA_EVENT 0 x01這樣就添加了一個新事件SEND_DATA_EVENT,該事件的ID是0 x01。 2022/7/1465周期發(fā)送邏輯在用戶應用程事件處理函數(shù)中,當終端節(jié)點加入網(wǎng)絡后啟動定時器,觸發(fā)第一次的事件SEND_DATA_EVENT,而在SEND_DATA_EVENT的事件處理程序中進行數(shù)據(jù)發(fā)送,同時啟動下一次的數(shù)據(jù)發(fā)送定時器,如此不斷循環(huán)下去。使用osal_set_event0函數(shù)設置SEND_DATA_EV
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- xx廠聘用合同范本
- 云南商標轉(zhuǎn)讓合同范本
- 倉庫搭建合同范本寫
- 合伙生意共同債務合同范本
- 合伙協(xié)議合同范例股權(quán)
- 辦公沙發(fā)采購合同范本
- 廠房定金合同范本
- 合同范例糾紛
- 琴行對公合作合同范本
- 共同債務合同范本
- 員工外宿免責協(xié)議書(2篇)
- IT科技產(chǎn)業(yè)云計算服務平臺開發(fā)方案
- 2025年中國航天科工招聘筆試參考題庫含答案解析
- 兒童教育總經(jīng)理聘任合同
- 血透室停電停水應急預案
- 4《公民的基本權(quán)利和義務》(第2課時)教學實錄-2024-2025學年道德與法治六年級上冊統(tǒng)編版
- 人教版小學數(shù)學三年級下冊第一單元《位置與方向(一)》單元測試
- 電力變壓器聲紋檢測技術(shù)導則
- 公司前臺接待禮儀培訓
- 2024解析:第四章光現(xiàn)象-基礎練(解析版)
- 黃連素的合成方法研究
評論
0/150
提交評論