您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 其它相关文档 > ZStack-SampleApp分析
在ZigBee协议中,协议本身已经定义了大部分内容,在基于ZigBee协议的应用开发中,用户只需要实现应用程序框架即可。应用程序框架中包含了最多240个应用程序对象。如果我们打开sampleApp工程,用户自己添加的应用任务程序在Zstack中的调用过程是:main()---osal_init_system()---osalInitTasks()---SampleApp_Init()在osalInitTasks()中实现了多个任务初始化的设置,而用户自己实现的SampleApp_Init()在最后,这里taskID随着任务的增加也随之递增。所以用户自己实现的任务的初始化操作应该在osalInitTasks()中增加。任务事件处理函数在tasksArr[]中添加。1、首先来看下主函数main()intmain(void)//主函数的功能就是完成初始化任务,然后进入OSAL{osal_int_disable(INTS_ALL);/*关闭中断*/HAL_BOARD_INIT();/*初始化硬件*zmain_vdd_check();/*电压检测,确保芯片能正常工作的电压*/zmain_ram_init();/*初始化stack存储区*/InitBoard(OB_COLD);/*初始化板载IO*/HalDriverInit();/*初始化硬件驱动*/osal_nv_init(NULL);/*初始化NV系统*/zmain_ext_addr();/*确定扩展地址(64位IEEE/物理地址)*/zgInit();/*初始化基本NV条目*/ZMacInit();/*初始化MAC*/#ifndefNONWKafInit();//SincetheAFisn'tatask,callit'sinitializationroutine#endif#ifdefLCD_SUPPORTEDHalLcdInit();#endifosal_init_system();/*初始化操作系统*/osal_int_enable(INTS_ALL);/*开启中断*/InitBoard(OB_READY);/*最终板载初始化*/zmain_dev_info();/*显示设备信息*/#ifdefLCD_SUPPORTED/*DisplaythedeviceinfoontheLCD*/zmain_lcd_init();#endifosal_start_system();//NoReturnfromhere没有返回,即进入操作系统!!!}2.1osal_init_system()——系统初始化函数Uint8osal_init_system(void){osal_mem_init();/*初始化内存分配系统*/osal_qHead=NULL;/*初始化系统消息队列*/#ifdefined(OSAL_TOTAL_MEM)osal_msg_cnt=0;#endifosalTimerInit();/*初始化定时器*/osal_pwrmgr_init();/*初始化电源管理系统*/osalInitTasks();//初始化系统任务//Setupefficientsearchforthefirstfreeblockofheap.osal_mem_kick();return(ZSUCCESS);}2.2osalInitTasks();——任务初始化函数voidosalInitTasks(void){uint8taskID=0;//(uint16*tasksEvents定义的是一个指针,实际上是一个任务数组)osal_mem_alloc()为当前OSAL中的各任务分配存储空间,函数返回指向任务缓冲区的指针,因此tasksEvents指向该任务数组的首地址。注意tasksEvents[]和后面谈到的tasksArr[]里的顺序是一一对应的,tasksArr[]中的第i个事件处理函数对应于tasksEvents[]中的第i个任务的事件。tasksEvents=(uint16*)osal_mem_alloc(sizeof(uint16)*tasksCnt);//osal_memset()把开辟的内存全部设置为0;sizeof(uint16)是4个字节,即一个任务的长度(同样是uint16定义),乘以任务数量tasksCnt,即全部内存空间osal_memset(tasksEvents,0,(sizeof(uint16)*tasksCnt));//OSAL.c中定义macTaskInit(taskID++);//初始化各层任务mac_taskID=0;nwk_init(taskID++);//nwk_taskID=1;Hal_Init(taskID++);//Hal_taskID=2;#ifdefined(MT_TASK)MT_TaskInit(taskID++);//MT_taskID=3;(ifdefined)#endifAPS_Init(taskID++);//APS_taskID=4;ZDApp_Init(taskID++);//ZDAPP_taskID=5;SampleApp_Init(taskID);//SampleApp_taskID=6;用户创建的任务}任务初始化,就是为系统的各个任务分配存储空间,当然,这个空间初始化时为全0(NULL),然后为各任务分配taskID,这里的顺序要注意:系统主循环函数里tasksEvents[idx]和tasksArr[idx]的idx与这里taskID是一一对应关系。数组tasksEvents[]里面元素是各任务事件,不是指向任务事件的指针。数组tasksArr[]是这个指针数组,里面元素是指向各任务事件处理函数的指针。这两个数组里面各元素的顺序要一一对应,因为后面需要相应任务调用相应事件处理函数。说明:这里重点是各任务的初始化,MAC层和NWK层的未开源看不到,先记录下用户自己添加的任务初始化函数SampleApp_Init(taskID);2.3SampleApp_Init(taskID);——用户应用任务初始化函数voidSampleApp_Init(uint8task_id){SampleApp_TaskID=task_id;//osal分配的任务ID,这里为6,随着用户添加任务的增多而改变SampleApp_NwkState=DEV_INIT;//设备状态设定为ZDO层中定义的初始化状态(无连接,表示该节点没有连接到Zigbee网络),初始化应用设备的网络类型,设备类型的改变都要产生一个事件—ZDO_STATE_CHANGE,从字面理解为ZDO状态发生了改变。所以在设备初始化的时候一定要把它初始化为什么状态都没有。那么它就要去检测整个环境,看是否能重新建立或者加入存在的网络。但是有一种情况例外,就是当NV_RESTORE被设置的候(NV_RESTORE是把信息保存在非易失存储器中),那么当设备断电或者某种意外重启时,由于网络状态存储在非易失存储器中,那么此时就只需要恢复其网络状态,而不需要重新建立或者加入网络了.这里需要设置NV_RESTORE宏定义。SampleApp_TransID=0;//消息发送ID(多消息时有顺序之分)将发送数据包的序列号初始化为0,在Zigbee协议栈中,每发送一个数据包,该发送序列号自动加1(协议栈里面的函数自动完成#ifdefined(BUILD_ALL_DEVICES)//TheDemotargetissetuptohaveBUILD_ALL_DEVICESandHOLD_AUTO_START//Wearelookingatajumper(definedinSampleAppHw.c)tobejumpered//together-iftheyare-wewillstartupacoordinator.Otherwise,//thedevicewillstartasarouter.if(readCoordinatorJumper())zgDeviceLogicalType=ZG_DEVICETYPE_COORDINATOR;elsezgDeviceLogicalType=ZG_DEVICETYPE_ROUTER;#endif//BUILD_ALL_DEVICES#ifdefined(HOLD_AUTO_START)//HOLD_AUTO_STARTisacompileoptionthatwillsurpressZDApp//fromstartingthedeviceandwaitfortheapplicationtostartthedevice.该段的意思是,如果设置了HOLD_AUTO_START宏定义,将会在启动芯片的时候会暂停启动流程,只有外部触发以后才会启动芯片。其实就是需要一个按钮触发它的启动流程。ZDOInitDevice(0);#endif/*设置发送数据的方式和目的地址寻址模式*///Setupfortheperiodicmessage'sdestinationaddress周期消息事件//Broadcasttoeveryone/*广播到所有设备*/SampleApp_Periodic_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;//发送模式:广播SampleApp_Periodic_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;//指定端点号EP20SampleApp_Periodic_DstAddr.addr.shortAddr=0xFFFF;//指定目的网络地址为广播地址//闪烁消息:发送到组/*设置endpointdescription.*/SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddrGroup;//(组寻址)SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;//EP20SampleApp_Flash_DstAddr.addr.shortAddr=SAMPLEAPP_FLASH_GROUP;组号0x0001//Fillouttheendpointdescription./*定义本设备用来通信的APS层端点描述符*/SampleApp_epDesc.endPoint=SAMPLEAPP_ENDPOINT;EP描述符的EP号:20SampleApp_epDesc.task_id=&SampleApp_TaskID;任务ID:6SampleApp_epDesc.simpleDesc=(SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;//SampleAppEP简单描述符SampleApp_epDesc.latencyReq=noLatencyReqs;//延时策略/*登记endpointdescription到AF,要对该应用进行初始化并在AF进行登记,告诉应用层有这么一个EP已经开通可以使用,*/afRegister(&SampleApp_epDesc);//Registerforallkeyevents-Thisappwillhandleallkeyevents/*登记所有的按键事件*/RegisterForKeys(SampleApp_TaskID);//Bydefault,alldevicesstartoutinGroup1为闪烁消息配置的组/*设定一个新的组*/SampleApp_Group.ID=0x0001;//组号osal_memcpy(SampleApp_Group.name,Group1,7);//设定组名aps_AddGroup(SAMPLEAPP_ENDPOINT,&SampleApp_Group);把组登记添加到APS中/*如果支持LCD,显示一串字符*/#ifdefined(LCD_SUPPORTED)//Hal
本文标题:ZStack-SampleApp分析
链接地址:https://www.777doc.com/doc-1851837 .html