Zigbee学习(二)协调器程序

********************************************************************* 在协议栈中控制LED闪烁 协调器程序(Coordinator.c) ********************************************************************* #include "OSAL.h" #include "ZGlobals.h" #include "AF.h" #include "aps_groups.h" #include "ZDApp.h" #include "Coordinator.h"//协调器头文件包含 #include "SampleApp.h" #include "SampleAppHw.h"#include "OnBoard.h"/* HAL */ #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h"/ //定义簇列表数组,cId_t为自定义类型,代表unsigned short型. //SAMPLEAPP_MAX_CLUSTERS 为簇命令个数簇命令有啥用,咱也不知道 const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_PERIODIC_CLUSTERID//用户自定义的簇命令代码 //SAMPLEAPP_FLASH_CLUSTERID }; //定义**简单**的端口描述变量 const SimpleDescriptionFormat_t SampleApp_SimpleDesc = { SAMPLEAPP_ENDPOINT,//int Endpoint; endPoint就是端口号 SAMPLEAPP_PROFID,//uint16 AppProfId[2]; 应用规范ID SAMPLEAPP_DEVICEID,//uint16 AppDeviceId[2]; 应用设备ID SAMPLEAPP_DEVICE_VERSION,//intAppDevVer:4; 设备版本号 SAMPLEAPP_FLAGS,//intAppFlags:4; 设备标志 SAMPLEAPP_MAX_CLUSTERS,//uint8AppNumInClusters; 簇命令个数 (cId_t *)SampleApp_ClusterList,//uint8 *pAppInClusterList; 簇命令数组指针 SAMPLEAPP_MAX_CLUSTERS,//uint8AppNumInClusters; (cId_t *)SampleApp_ClusterList//uint8 *pAppInClusterList; }; endPointDesc_t SampleApp_epDesc; /*endPointDesc_t为结构体类型,说明如下 typedef struct{ byte endPoint; //端口号 byte *taskId; //指向应用任务号的指针 SimpleDescriptionFormat_t *simpleDesc; //指向简单的端口描述变量的指针 afNeworkLatencyReq_tlantencyReq; //端口的延迟响应 }endPointDesc_t; */ //由此可见endPointDesc_t类型包含SimpleDescriptionFormat_t类型的信息。 //SampleApp_epDesc是SampleApp_SimpleDesc的扩充,由于SampleApp_SimpleDesc为const常量,在应用程序中读写应用端口号访问的是SampleApp_epDesc.endPoint。而非SampleApp_SimpleDesc.endPoint//定义变量SampleApp_TaskID存放应用程序中的任务号 uint8 SampleApp_TaskID; // Task ID for internal task/event processing // This variable will be received when // SampleApp_Init() is called. //定义变量 SampleApp_NwkState存放节点的网络状态 devStates_t SampleApp_NwkState; /* devStates_t为枚举类型,定义如下: typedef enum { DEV_HOLD,已初始化,不自动启动 DEV_INIT,已初始化,无任何连接 DEV_NWK_JOINING,//发现个域网加入 DEV_NWK_REJION.重新加入个域网 DEV_END_DEVICE_UNAUTH,已加入但未被认证,为终端设备 DEV_END_DEVICE,已认证,已启动,为终端设备 DEV_ROUTER,已认证,已启动,为路由设备 DEC_COORD_STARTING,已启动,为协调器 DEV_ZB_COORD,已以协调器角色启动 DEV_NWK_ORPHAN 无父信息 }devStates_t//定义变量SampleApp_TransID,存放数据包编号,以便检查数据丢包,每传输一个数据包,此变量+1 uint8 SampleApp_TransID; // This is the unique message ID (counter)afAddrType_t SampleApp_Periodic_DstAddr; afAddrType_t SampleApp_Flash_DstAddr; aps_Group_t SampleApp_Group; uint8 SampleAppPeriodicCounter = 0; uint8 SampleAppFlashCounter = 0; /********************************************************************* * LOCAL FUNCTIONS */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ); void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pckt ); void SampleApp_SendPeriodicMessage( void ); void SampleApp_SendFlashMessage( uint16 flashTime ); /********************************************************************* * @fnSampleApp_Init * * @briefInitialization function for the Generic App Task. *This is called during initialization and should contain *any application specific initialization (ie. hardware *initialization/setup, table initialization, power up *notificaiton ... ). * * @paramtask_id - the ID assigned by OSAL.This ID should be *used to send messages and set timers. * * @returnnone */ //初始化程序代码,做了两件事,一:对文件中的全局变量赋值。二:注册应用端口 void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id; //任务号初始化 SampleApp_NwkState = DEV_INIT; //节点状态初始化(已认证,已初始化,为终端设备) SampleApp_TransID = 0; //传输ID初始化,初始值0(检测数据包丢包)// Device hardware initialization can be added here or in main() (Zmain.c). // If the hardware is application specific - add it here. // If the hardware is other parts of the device add it in main(). #if defined ( BUILD_ALL_DEVICES ) // The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START // We are looking at a jumper (defined in SampleAppHw.c) to be jumpered // together - if they are - we will start up a coordinator. Otherwise, // the device will start as a router. if ( readCoordinatorJumper() ) zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR; else zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; #endif // BUILD_ALL_DEVICES#if defined ( HOLD_AUTO_START ) // HOLD_AUTO_START is a compile option that will surpress ZDApp //from starting the device and wait for the application to //start the device. ZDOInitDevice(0); #endif// Setup for the periodic message's destination address // Broadcast to everyone SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // Setup for the flash command's destination address - Group 1 SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // Fill out the endpoint description. SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; //设置应用端口号 SampleApp_epDesc.task_id = &SampleApp_TaskID; //设置应用端口任务号 SampleApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc; //设置应用的簇命令数,簇列表地址等参数,通过指针传递 SampleApp_epDesc.latencyReq = noLatencyReqs; //设置应用响应延时noLatencyReqs在AF.h中定义为0// Register the endpoint description with the AF //用afRegister()函数注册应用端口SampleApp_epDesc,只有当端口注册后OSAL才能为其提供服务 afRegister( &SampleApp_epDesc ); // afStatus afRegister(endPointDesc_t *epDesc) //功能:注册一个应用端口,其参数是应用端口变量的地址,返回值为注册后的状态// Register for all key events - This app will handle all key events RegisterForKeys( SampleApp_TaskID ); // By default, all devices start out in Group 1 SampleApp_Group.ID = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); #if defined ( LCD_SUPPORTED ) HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); #endif }/********************************************************************* * @fnSampleApp_ProcessEvent * * @briefGeneric Application Task event processor.This function *is called to process all events for the task.Events *include timers, messages and any other user defined events. * * @paramtask_id- The OSAL assigned task ID. * @paramevents - events to process.This is a bit map and can *contain more than one event. * * @returnnone */ ///事件处理程序 uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { //定义指向接受消息的指针 MSGpkt afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameterif ( events & SYS_EVENT_MSG ) //当系统事件发生 { //从消息队列中取消息 MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); while ( MSGpkt )//当有消息 { switch ( MSGpkt->hdr.event )//判断消息中的事件域 { // Received when a key is pressed case KEY_CHANGE: SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; // Received when a messages is received (OTA) for this endpoint case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ); break; // Received whenever the device changes state in the network case ZDO_STATE_CHANGE:///ZDO状态变化事件 SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); //读设备状态 if ( (SampleApp_NwkState == DEV_ZB_COORD)//若为协调器||路由器||终端节点 || (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { // Start sending the periodic message in a regular interval. //延时一段时间后,设置用事件 osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { // Device is no longer in the network } break; default: break; }// Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); //释放消息所占存储空间// Next - if one is available MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); //从队列获取消息 }// return unprocessed events return (events ^ SYS_EVENT_MSG); //返回未处理完的系统事件 }// Send a message out - This event is generated by a timer //(setup in SampleApp_Init()). //用户事件处理 if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )是用户事件吗 { HalLedSet(HAL_LED1,HAL_LED_MODE_TOGGLE); //LED1状态翻转 // Send the periodic message SampleApp_SendPeriodicMessage(); //再次触发用户事件 // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); //设置下次启动事件的时间// return unprocessed events return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); 返回未处理完的用户时间 }// Discard unknown events return 0; }/********************************************************************* * Event Generation Functions */ /********************************************************************* * @fnSampleApp_HandleKeys * * @briefHandles all key events for this device. * * @paramshift - true if in shift/alt. * @paramkeys - bit field for key events. Valid entries: *HAL_KEY_SW_2 *HAL_KEY_SW_1 * * @returnnone */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ) { (void)shift; // Intentionally unreferenced parameterif ( keys & HAL_KEY_SW_1 ) { /* This key sends the Flash Command is sent to Group 1. * This device will not receive the Flash Command from this * device (even if it belongs to group 1). */ SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ); }if ( keys & HAL_KEY_SW_2 ) { /* The Flashr Command is sent to Group 1. * This key toggles this device in and out of group 1. * If this device doesn't belong to group 1, this application * will not receive the Flash command sent to group 1. */ aps_Group_t *grp; grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); if ( grp ) { // Remove from the group aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); } else { // Add to the flash group aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); } } }/********************************************************************* * LOCAL FUNCTIONS *//********************************************************************* * @fnSampleApp_MessageMSGCB * * @briefData message processor callback.This function processes *any incoming data - probably from other devices.So, based *on cluster ID, perform the intended action. * * @paramnone * * @returnnone */ void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { uint16 flashTime; switch ( pkt->clusterId ) { case SAMPLEAPP_PERIODIC_CLUSTERID: break; case SAMPLEAPP_FLASH_CLUSTERID: flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] ); HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); break; } }/********************************************************************* * @fnSampleApp_SendPeriodicMessage * * @briefSend the periodic message. * * @paramnone * * @returnnone */ void SampleApp_SendPeriodicMessage( void ) { if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 1, (uint8*)&SampleAppPeriodicCounter, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } }/********************************************************************* * @fnSampleApp_SendFlashMessage * * @briefSend the flash message to group 1. * * @paramflashTime - in milliseconds * * @returnnone */ void SampleApp_SendFlashMessage( uint16 flashTime ) { uint8 buffer[3]; buffer[0] = (uint8)(SampleAppFlashCounter++); buffer[1] = LO_UINT16( flashTime ); buffer[2] = HI_UINT16( flashTime ); if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, 3, buffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } }/********************************************************************* *********************************************************************/

********************************************************************* 在协议栈中控制LED闪烁 协调器程序(Coordinator.h) *********************************************************************#ifndef SAMPLEAPP_H #define SAMPLEAPP_H#ifdef __cplusplus extern "C" { #endif/********************************************************************* * INCLUDES */ #include "ZComDef.h"/********************************************************************* * CONSTANTS */// These constants are only for example and should be changed to the // device's needs #define SAMPLEAPP_ENDPOINT20#define SAMPLEAPP_PROFID0x0F08 #define SAMPLEAPP_DEVICEID0x0001 #define SAMPLEAPP_DEVICE_VERSION0 #define SAMPLEAPP_FLAGS0#define SAMPLEAPP_MAX_CLUSTERS1//66改 #define SAMPLEAPP_PERIODIC_CLUSTERID 1 #define SAMPLEAPP_FLASH_CLUSTERID2// Send Message Timeout #define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT500// 发送时间时间间隔0.5s//定义用户事件 // Application Events (OSAL) - These are bit weighted definitions. #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT0x0001// Group ID for Flash Command #define SAMPLEAPP_FLASH_GROUP0x0001// Flash Command Duration - in milliseconds #define SAMPLEAPP_FLASH_DURATION1000/********************************************************************* * MACROS *//********************************************************************* * FUNCTIONS *//* * Task Initialization for the Generic Application */ extern void SampleApp_Init( uint8 task_id ); /* * Task Event Processor for the Generic Application */ extern UINT16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ); /********************************************************************* *********************************************************************/#ifdef __cplusplus } #endif#endif /* SAMPLEAPP_H */

*********************************************************************OSAL_SampApp.h文件 ********************************************************************* #include "ZComDef.h" #include "hal_drivers.h" #include "OSAL.h" #include "OSAL_Tasks.h"#if defined ( MT_TASK ) #include "MT.h" #include "MT_TASK.h" #endif#include "nwk.h" #include "APS.h" #include "ZDApp.h" #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ) #include "ZDNwkMgr.h" #endif #if defined ( ZIGBEE_FRAGMENTATION ) #include "aps_frag.h" #endif#include "Coordinator.h"/********************************************************************* * GLOBAL VARIABLES */// The order in this table must be identical to the task initialization calls below in osalInitTask. const pTaskEventHandlerFn tasksArr[] = { macEventLoop, nwk_event_loop, Hal_ProcessEvent, #if defined( MT_TASK ) MT_ProcessEvent, #endif APS_event_loop, #if defined ( ZIGBEE_FRAGMENTATION ) APSF_ProcessEvent, #endif ZDApp_event_loop, #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ) ZDNwkMgr_event_loop, #endif SampleApp_ProcessEvent }; const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] ); uint16 *tasksEvents; /********************************************************************* * FUNCTIONS *********************************************************************//********************************************************************* * @fnosalInitTasks * * @briefThis function invokes the initialization function for each task. * * @paramvoid * * @returnnone */ void osalInitTasks( void ) { uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); macTaskInit( taskID++ ); nwk_init( taskID++ ); Hal_Init( taskID++ ); #if defined( MT_TASK ) MT_TaskInit( taskID++ ); #endif APS_Init( taskID++ ); #if defined ( ZIGBEE_FRAGMENTATION ) APSF_Init( taskID++ ); #endif ZDApp_Init( taskID++ ); #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ) ZDNwkMgr_Init( taskID++ ); #endif SampleApp_Init( taskID ); }/********************************************************************* *********************************************************************/

    推荐阅读