ZStack之ZDApp_Init解析

来源:互联网 发布:哗啦啦餐饮软件好用吗 编辑:程序博客网 时间:2024/06/07 00:31


1、http://www.cnblogs.com/cherishui/p/3689376.html

自己去看吧

2**************************************************************************************************

ZDApp_init()是ZD层的初始化函数。

ZDO即zigbee device object(zigbee设备对象,用来描述设备的状态)TI的ZDO层的API函数提供了创建网络,发现网络,假如网络,绑定应用终节点和管理安全的功能。ZDO层所有功能的定义和调用都在ZDProfile里面。


ZDProflie(代码中)描述了zigbee设备在ZDO执行的每一个细节,它定义了设备的description和cluster(簇就是一组应用的命令和回复的集合),通过定义消息结构体ZDProfile提供:设备建立网络,设备和服务发现,终端绑定、绑定和不绑定,网络管理服务 功能。(从TI提供的官方文档上面,我们获得了如上信息。)


默认startup a network是在ZDApp_init()里面。但是,application可以不用理会这个默认习惯。条件编译选项选择了HOLD_AUTO_START、NV_RESTORE,application就能控制设备网络的开始,通过调用ZDOInitDevice()。


void ZDApp_Init( byte task_id )
{
  u*。。。。。。。。。。。。

} /* ZDO_Init() */


这里启动网络,在条件编译里面设置了hold_auto_start的话,检测到按键SW5后系统才会继续运行


网路设备的启动过程

无论是协调器还是路由器或是终端设备,其启动过程至网络初始步骤均是一样的,只是不同设备的配置文件在编译时有所区别:

协调器:F8wCoord.cfg

路由器:F8wRouter.cfg

终端设备:F8wEndev.cfg

启动过程:

1、int main( void )中的 osal_init_system();

2、 osal_init_system();中的 osalInitTasks();

3、osalInitTasks();中的 ZDApp_Init( taskID++ );和SerialApp_Init( taskID );

4、void ZDApp_Init( uint8 task_id )--- ZDOInitDevice( uint16 startDelay )----ZDApp_NetworkInit( uint16 delay ) 

5、UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )中的

 ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
                     DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );


协调器建网

void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
     devState = DEV_COORD_STARTING;
      ret = NLME_NetworkFormationRequest( zgConfigPANID, zgApsUseExtendedPANID, zgDefaultChannelList,
                                          zgDefaultStartingScanDuration, beaconOrder,
                                          superframeOrder, false );
……
}

路由器入网

void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
 devState = DEV_NWK_DISC;
……
}




void ZDApp_Init( uint8 task_id )
        {
                ZDAppTaskID = task_id;
                // Initialize the ZDO global device short address storage
                ZDAppNwkAddr.addrMode = Addr16Bit;
                ZDAppNwkAddr.addr.shortAddr = INVALID_NODE_ADDR;
                (void)NLME_GetExtAddr(); // 找到IEEE设备64位地址
                // 检查是否定义了编译选项HOLD_AUTO_START,如果定义了HOLD_AUTO_START,则设置devState = DEV_HOLD,否则设置devState = DEV_INIT ZDAppCheckForHoldKey();
                // 根据设备类型初始化ZDO 项目并启动设备 
                ZDO_Init();
                // 注册终端节点
                afRegister( (endPointDesc_t *)&ZDApp_epDesc );
                #if defined( ZDO_USERDESC_RESPONSE )
                        ZDApp_InitUserDesc();
                #endif // ZDO_USERDESC_RESPONSE
                // 是否启动设备
                if ( devState != DEV_HOLD )
                {
                        ZDOInitDevice( 0 ); //是否从非易失性存储器中操作网络属性
                }
                ZDApp_RegisterCBs(); //注册回调函数
        } /* ZDApp_Init() */

如果设置devState为DEV_HOLD,则不会执行ZDOInitDevice;相反,系统会调用函数是设备组网或者入网。看下这个函数完成的功能是什么样子的。ZDOInitDevice是设备在网络中启动。它会读取NV中的ZCD_NV_STARTUP_OPTION选项决定是否恢复网络状态。如果应用层强制进行新的join操作,它应该在调用这个函数之前设置ZCD_NV_STARTUP_OPTION中的ZCD_STARTOPT_DEFAULT_NETWORK_STATE位。可以调用zgWrieStartupOptions()函数完成这些设置。

uint8 ZDOInitDevice( uint16 startDelay )
        {
                uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE; //0x01
                uint16 extendedDelay = 0;
                if ( devState == DEV_HOLD )
                { 
                        // Initialize the RAM items table, in case an NV item has been updated.zgInitItems( FALSE );
                }
                ZDConfig_InitDescriptors();
                //devtag.071807.todo - fix this temporary solution
                _NIB.CapabilityInfo = ZDO_Config_Node_Descriptor.CapabilityFlags;
                devState = DEV_INIT; // Remove the Hold state
                // 函数读取NV项目ZCD_NV_LEAVE_CTRL的值,ZDApp_LeaveCtrl指向这个值
                函数读取NV项目ZCD_NV_LEAVE_CTRL的值,ZDApp_LeaveCtrl指向这个值
                ZDApp_LeaveCtrlInit();
                // Check leave control reset settings设备的断开会造成DEV_HOLD状态
                ZDApp_LeaveCtrlStartup( &devState, &startDelay );
                // Leave may make the hold state come back
                if ( devState == DEV_HOLD )
                {
                        // 设置启动选项
                        zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
                        //通知应用层触发事件 
                        osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
                        return ( ZDO_INITDEV_LEAVE_NOT_STARTED ); // Don't join - (one time).
                }
                #if defined ( NV_RESTORE )
                // Get Keypad directly to see if a reset nv is needed.
                // Hold down the SW_BYPASS_NV key (defined in OnBoard.h)
                // while booting to skip past NV Restore.
                if ( HalKeyRead() == SW_BYPASS_NV )
                        networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
                else
                {
                        // 通过读取ZCD_NV_STARTUP_OPTION选项决定是否进行网络恢复
                        networkStateNV = ZDApp_ReadNetworkRestoreState();
                }
                if ( networkStateNV == ZDO_INITDEV_RESTORED_NETWORK_STATE )
                {
                        networkStateNV = ZDApp_RestoreNetworkState();
                        //如果进行网络状态的恢复,则从NV中读取相关参数。
                        通过ZDAppNwkAddr.addr.shortAddr = NLME_GetShortAddr();
                        if ( ZDAppNwkAddr.addr.shortAddr == 0 )
                        ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;
                        devStartMode = MODE_RESUME;
                        osal_cpyExtAddr( ZDO_UseExtendedPANID, _NIB.extendedPANID );
                获取shortAddress,并设置设备启动状态
                }
                else
                {
                        // Wipe out the network state in NV
                        NLME_InitNV();
                        NLME_SetDefaultNV();
                }
                #endif
                if ( networkStateNV == ZDO_INITDEV_NEW_NETWORK_STATE )//如果是要启动新的网络
                {
                        ZDAppDetermineDeviceType();//根据选项设置设备的网络类型
                        // Only delay if joining network - not restoring network state
                        extendedDelay = (uint16)((NWK_START_DELAY + startDelay)
                        + (osal_rand() & EXTENDED_JOINING_RANDOM_MASK));
                }
                // Initialize the security for type of device
                ZDApp_SecInit( networkStateNV );
                // 触发启动网络
                ZDApp_NetworkInit( extendedDelay );
                // set broadcast address mask to support broadcast filtering,用于处理合法的广播地址
                NLME_SetBroadcastFilter( ZDO_Config_Node_Descriptor.CapabilityFlags );
                属性定义在ZDConfig_InitDescriptors();函数中,具体根据设备不同有以下几种:
                // MAC Capabilities
                if ( ZSTACK_ROUTER_BUILD )
                {
                        ZDO_Config_Node_Descriptor.CapabilityFlags 
                        = (CAPINFO_DEVICETYPE_FFD | CAPINFO_POWER_AC | CAPINFO_RCVR_ON_IDLE);
                        if ( ZG_BUILD_COORDINATOR_TYPE && ZG_DEVICE_COORDINATOR_TYPE )
                        ZDO_Config_Node_Descriptor.CapabilityFlags |= CAPINFO_ALTPANCOORD;
                }
                else if ( ZSTACK_END_DEVICE_BUILD )
                {
                        ZDO_Config_Node_Descriptor.CapabilityFlags = (CAPINFO_DEVICETYPE_RFD
                        #if ( RFD_RCVC_ALWAYS_ON == TRUE)| CAPINFO_RCVR_ON_IDLE
                        #endif
                        );
                }
                return ( networkStateNV );



0 0
原创粉丝点击