Chinaunix首页 | 论坛 | 博客
  • 博客访问: 310214
  • 博文数量: 78
  • 博客积分: 3635
  • 博客等级: 中校
  • 技术积分: 1115
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-28 09:35
文章分类

全部博文(78)

文章存档

2011年(13)

2010年(65)

我的朋友

分类:

2011-04-14 19:26:43

 

使用的协议栈版本信息: ZigBee2006\ZStack-1.4.3-1.2.1
Zigbee网络设备启动流程—协调器(非自启动模式HOLD_AUTO_START)
                      —以SimpleApp的灯节点SimpleControllerEB为例.

灯节点按K1则作为协调器启动,按K2则作为路由器启动.这里以按K1作为协调器启动为例.

1、灯节点预编译信息
通过project->options->c/c++compiler->extraOptions可以看到灯节点所带的配置文件为:
-f $PROJ_DIR$\..\..\..\Tools\CC2430DB\f8wCoord.cfg
-f $PROJ_DIR$\..\..\..\Tools\CC2430DB\f8wConfig.cfg

即编译了ZDO_COORDINATOR和RTR_NWK.

通过project->options->c/c++compiler->Preprocessor->Defined symbols可以看到灯节点预编译包含了:
CC2430EB; HOLD_AUTO_START; SOFT_START; REFLECTOR; NV_INIT; LCD_SUPPORTED
xNV_RESTORE; xZTOOL_P1; xMT_TASK; xMT_SAPI_FUNC; xMT_SAPI_CB_FUNC

可以看到编译了HOLD_AUTO_START和SOFT_START.
因而初始化:
devState = DEV_HOLD(见基本问题说明3.编译了HOLD_AUTO_START)
devStartMode = MODE_JOIN(见基本问题说明4.编译了SOFT_START)
zgDeviceLogicalType = DEVICE_LOGICAL_TYPE=ZG_DEVICETYPE_SOFT(见基本问题说明5.编译了SOFT_START)
ZDO_Config_Node_Descriptor.LogicalType=NODETYPE_ROUTER(见基本问题说明6.编译了SOFT_START和RTR_NWK)

2、具体流程
main()->osal_init_system()->osalInitTasks()->ZDApp_Init()
进入ZDApp_Init()函数:
**************************************
void ZDApp_Init( byte task_id )
{
  uint8 capabilities;

  // Save the task ID
  ZDAppTaskID = task_id;

  // Initialize the ZDO global device short address storage
  ZDAppNwkAddr.addrMode = Addr16Bit;
  ZDAppNwkAddr.addr.shortAddr = INVALID_NODE_ADDR;//0xFFFE
  (void)NLME_GetExtAddr(); 
// Load the saveExtAddr pointer.

  // Check for manual"Hold Auto Start"
  //检测到有手工置位SW_1则会设置devState = DEV_HOLD,从而避开网络初始化
  ZDAppCheckForHoldKey();

  // Initialize ZDO items and setup the device - type of device to create.
  ZDO_Init(); 
//通过判断预编译来开启一些函数功能


  // Register the endpoint description with the AF
  // This task doesn't have a Simple description, but we still need
  // to register the endpoint.

  afRegister( (endPointDesc_t *)&ZDApp_epDesc );

#if defined( ZDO_USERDESC_RESPONSE )
  ZDApp_InitUserDesc();
#endif
// ZDO_USERDESC_RESPONSE

  // set broadcast address mask to support broadcast filtering
  NLME_GetRequest(nwkCapabilityInfo, 0, &capabilities);
  NLME_SetBroadcastFilter( capabilities );

  // Start the device?
  if ( devState != DEV_HOLD )
  {
    ZDOInitDevice( 0 );
  }
  /*如果devState=DEV_HOLD,则不会调用ZDOInitDevice()来初始化网络
    即不组网也不入网.LED4闪烁等待应用程序来开启设备并初始化网络
  */
  else
  {
    // Blink LED to indicate HOLD_START
    HalLedBlink ( HAL_LED_4, 0, 50, 500 );
  }

  ZDApp_RegisterCBs();
}
**************************************
ZDApp_Init()中一些函数可以见主要函数说明1.记录下灯节点里ZDO_Init()这个函数.
*********************
void ZDO_Init( void )
{
  // Initialize ZD items
  #if defined ( REFLECTOR )
  ZDO_EDBind = NULL;
  #endif

  // Setup the device - type of device to create.
  ZDODeviceSetup();
}
*********************
灯节点预编译了REFLECTOR,使用源绑定机制.进入ZDODeviceSetup():
*********************
//根据编译选项来设置功能函数;
static void ZDODeviceSetup( void )
{
#if defined( ZDO_COORDINATOR )   //编译了ZDO_COORDINATOR
  NLME_CoordinatorInit();
#endif

#if defined ( REFLECTOR )                 //编译了REFLECTOR
  #if defined ( ZDO_COORDINATOR )  //编译了REFLECTOR且编译了ZDO_COORDINATOR
    APS_ReflectorInit( APS_REFLECTOR_PUBLIC );
  #else  //编译了REFLECTOR且编译了ZR或ED
    APS_ReflectorInit( APS_REFLECTOR_PRIVATE );
  #endif
#endif

    //没有编译ZDO_COORDINATOR或者编译了SOFT_START
#if !defined( ZDO_COORDINATOR ) || defined( SOFT_START )
  NLME_DeviceJoiningInit();
#endif
}
*********************
灯节点编译了ZDO_COORDINATOR、RTR_NWK、REFLECTOR和SOFT_START.因而启动的功能函数有:
NLME_CoordinatorInit(); APS_ReflectorInit( APS_REFLECTOR_PUBLIC );NLME_DeviceJoiningIni()
回到ZDApp_Init(),因为灯节点编译了HOLD_AUTO_START,则devState = DEV_HOLD,也就可以不用管有没有手工置位SW1了.因此不会进入ZDOInitDevice()来初始化设备(建网或入网).而是通过LED4的闪烁来指示这是一个非自动启动模式,等待应用程序来初始化设备.ZDApp_Init()初始化结束后再进入SAPI_Init():
**************************************
void osalInitTasks( void )
{
  …………
  macTaskInit( taskID++ );
  nwk_init( taskID++ );
  Hal_Init( taskID++ );
#if defined( MT_TASK )
  MT_TaskInit( taskID++ );
#endif
  APS_Init( taskID++ );
  ZDApp_Init( taskID++ );
  SAPI_Init( taskID );
}
**************************************
看下SAPI_Init():
**************************************
void SAPI_Init( byte task_id )
{
  …………
  if ( HalKeyRead () == HAL_KEY_SW_1)
  {
    //期间如果按下SW1键,则禁止自动启动和NV存储功能,更新配置重启
    // If SW5 is pressed and held while powerup, force auto-start and nv-restore off and reset
    startOptions = ZCD_STARTOPT_CLEAR_STATE | ZCD_STARTOPT_CLEAR_CONFIG;  //默认启动状态和配置
    //startOptions作为默认启动项配置,存到NV条目ZCD_NV_STARTUP_OPTION中
    zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
    zb_SystemReset();  //复位系统
  }
 
#endif // HAL_KEY
#ifdef LCD_SUPPORTED
   Print8(HAL_LCD_LINE_2 ,20,"Simple",1);
#endif
  // Set an event to start the application
  osal_set_event(task_id, ZB_ENTRY_EVENT);
}
**************************************
按键SW1(个人记录中按键有点乱,具体查看映射函数)功能和SW_BYPASS_NV、SW_BYPASS_START类似,置位可以避开一些功能.
可以看到触发sapi_TaskID的ZB_ENTRY_EVENT事件,来看下对ZB_ENTRY_EVENT的处理:
**************************************
  if ( events & ZB_ENTRY_EVENT )    /*sapi启动事件*/
  {
    uint8 startOptions;
    // Give indication to application of device startup
    zb_HandleOsalEvent( ZB_ENTRY_EVENT );

    // LED off cancels HOLD_AUTO_START blink set in the stack
    HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF); 
//关闭指示HOLD_AUTO_START的LED4

    //读配置
    zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
    if ( startOptions & ZCD_STARTOPT_AUTO_START )  //自动启动
    {
      zb_StartRequest();
    }
    else
    {
      //LED2闪烁指示需要外部输入来配置信息再重启设备
      // blink leds and wait for external input to config and restart
      HalLedBlink(HAL_LED_2, 0, 50, 500);
#if defined SENSOR
    …………
    }

    return (events ^ ZB_ENTRY_EVENT );
  }
**************************************
从程序中可以看到首先读NV条目ZCD_NV_STARTUP_OPTION所存储的值,如果是ZCD_STARTOPT_AUTO_START则调用zb_StartRequest()来请求启动设备.NV条目ZCD_NV_STARTUP_OPTION的值在zgInit()中初始化为默认值(暂时估计为0,见基本问题说明9),因此这里不会调用zb_StartRequest()启动设备,而是LED2闪烁来指示需要外部输入来控制.
  作为一个单一设备,main()函数中各项功能已经初始化完成并进入了系统主循环函数osal_start_system(),要不然也不会处理ZB_ENTRY_EVENT事件,只是这个时候还没有启动作为一个网络设备的功能.接下来就通过按键来启动,灯节点按下K1,按键处理函数处理如下:
**************************************
    if ( keys & HAL_KEY_SW_1 )
    {
      /*初始化myAppState = APP_INIT,等灯设备逻辑类型确定并成功建网/入网,
        zb_StartRequest()会产生回调函数zb_StartConfirm(),如果成功则设置
        myAppState = APP_START,因而再按K1执行允许绑定功能.
       */
      if ( myAppState == APP_INIT  )
      {
       
// In the init state, keys are used to indicate the logical mode.
        // Key 1 starts device as a coordinator

        zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
        if ( logicalType != ZG_DEVICETYPE_ENDDEVICE )
        {
          logicalType = ZG_DEVICETYPE_COORDINATOR;  //协调器
          zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        }

        // Do more configuration if necessary and then restart device with auto-start bit set
        // write endpoint to simple desc...dont pass it in start req..then reset

        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();

      }
      else
      {
        // Initiate a binding
        zb_AllowBind( myAllowBindTimeout );  //默认为10S,myAllowBindTimeout=10
      }
    }
**************************************
按K1选择逻辑类型logicalType = ZG_DEVICETYPE_COORDINATOR,写入NV条目ZCD_NV_LOGICAL_TYPE,这里改变了ZDO全局变量zgDeviceLogicalType的值.灯节点中zgDeviceLogicalType被初始化为zgDeviceLogicalType = DEVICE_LOGICAL_TYPE=ZG_DEVICETYPE_SOFT(可选类型),而通过按K1,
zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR.(见基本问题说明5).
然后把启动选项startOptions = ZCD_STARTOPT_AUTO_START的值写入NV条目ZCD_NV_STARTUP_OPTION中.下次读取NV条目ZCD_NV_STARTUP_OPTION的值就为ZCD_STARTOPT_AUTO_START(因此会在对ZB_ENTRY_EVENT的处理中触发进入zb_StartRequest()).
最后重启系统.重新经过流程main()->osal_init_system()->osalInitTasks()->ZDApp_Init()->SAPI_Init()->触发sapi_TaskID的ZB_ENTRY_EVENT事件
此时
    zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
    if ( startOptions & ZCD_STARTOPT_AUTO_START )//自动启动
    {
      zb_StartRequest();
    }
再读取NV条目ZCD_NV_STARTUP_OPTION值时为ZCD_STARTOPT_AUTO_START,因而进入zb_StartRequest():
**************************************
 * @fn          zb_StartRequest
 *
 * @brief       The zb_StartRequest function starts the ZigBee stack.  When the
 *              ZigBee stack starts, the device reads configuration parameters
 *              from Nonvolatile memory and the device joins its network.  The
 *              ZigBee stack calls the zb_StartConrifm callback function when
 *              the startup process completes.
 *
 * @param       none
 *
 * @return      none
 */
void zb_StartRequest()
{
  uint8 logicalType;

  // Start the device
  // start delay = min(NWK_START_DELAY, zgStartDelay) + rand() - only for fresh start, not restore
  if ( zgStartDelay < NWK_START_DELAY )
    zgStartDelay = 0;
  else
    zgStartDelay -= NWK_START_DELAY;

  // check that bad combinations of compile flag definitions and device type
  /*
  // Values for ZCD_NV_LOGICAL_TYPE (zgDeviceLogicalType)
  #define ZG_DEVICETYPE_COORDINATOR      0x00(协调器)
  #define ZG_DEVICETYPE_ROUTER           0x01(路由器)
  #define ZG_DEVICETYPE_ENDDEVICE        0x02(终端)
  #define ZG_DEVICETYPE_SOFT             0x03(可选择类型)
  */
  //读取存储在NV里的设备ZCD_NV_LOGICAL_TYPE
  zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
 
  //检查错误的参数.
  //如:logicalType>0x02(可选择类型选择后不是协调器就是路由器);定义
  //了协调器,但logicalType为终端设备;
  //只可能是路由器时logicalType不为路由器;未编译RTR_NWK功能却定义了
  //logicalType为协调器;只可能为终端时logicalType却未定义为终端;
   if (  ( logicalType > ZG_DEVICETYPE_ENDDEVICE )        ||
#if defined( RTR_NWK )
  #if defined( ZDO_COORDINATOR )
          // Only RTR or Coord possible
         ( logicalType == ZG_DEVICETYPE_ENDDEVICE )   ||
  #else
          // Only RTR possible
          ( logicalType != ZG_DEVICETYPE_ROUTER )     ||
  #endif
#else
  #if defined( ZDO_COORDINATOR )
          // Error
          ( 1 )                                     ||
  #else
          // only ED possible
          ( logicalType != ZG_DEVICETYPE_ENDDEVICE )  ||
  #endif
#endif
          ( 0 ) )
   {
     // error configuration
     SAPI_SendCback( SAPICB_START_CNF, ZInvalidParameter, 0 );  //发送错误报告
   }
   else  //设备逻辑类型参数都正确则调用ZDOInitDevice()
   {
     ZDOInitDevice(zgStartDelay);
   }

  return;
}

**************************************
读取设备存储在NV条目ZCD_NV_LOGICAL_TYPE中的逻辑类型参数(这里灯节点按K1逻辑类型参数为ZG_DEVICETYPE_COORDINATOR),并检验是否有错误,正确则调用ZDOInitDevice(zgStartDelay).看下ZDOInitDevice():
**************************************
uint8 ZDOInitDevice( uint16 startDelay )
{
    //初始化设备网络状态为ZDO_INITDEV_NEW_NETWORK_STATE:新的网络状态.
    //可能意味着ZCD_NV_STARTUP_OPTION不能恢复,或没有任何网络状态恢复
  uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
  uint16 extendedDelay = 0;

  devState = DEV_INIT;    // Remove the Hold state

  // Initialize leave control logic
  //函数读取NV项目ZCD_NV_LEAVE_CTRL的值,ZDApp_LeaveCtrl指向这个值
  ZDApp_LeaveCtrlInit();

  // Check leave control reset settings
  ZDApp_LeaveCtrlStartup( &devState, &startDelay );

  // Leave may make the hold state come back
  //以上两个函数设置了对设备离开时的控制,如果有延时则延时,没有则
  //把设备状态设为DEV_HOLD
  if ( devState == DEV_HOLD )
    //ZDO_INITDEV_LEAVE_NOT_STARTED:该设备没有在网络中,下次调用才启用.
    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 )
    //SW_BYPASS_NV按键处于按下状态时,则避开网络层的NV存储
    networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;  //设备网络状态为新的网络状态
 
  else
  {
    // Determine if NV should be restored
    //函数返回的设备网络状态要么是新的网络状态;要么是恢复的网络状态;以此
    //来确定要不要读取NV里相应条目来恢复网络先前状态
    networkStateNV = ZDApp_ReadNetworkRestoreState();
  }

   //如果设备的网络状态为恢复的网络状态
  if ( networkStateNV == ZDO_INITDEV_RESTORED_NETWORK_STATE )
  {
    //恢复先前的网络状态,把 devStartMode = MODE_RESUME!!!!
    networkStateNV = ZDApp_RestoreNetworkState();
  }
  else  //如果设备的网络状态为新的网络状态,在下面进行处理
  {
    // Wipe out(清除) the network state in NV
    NLME_InitNV();
    NLME_SetDefaultNV();//设置默认NV条目
  }
#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 device security
  ZDApp_SecInit( networkStateNV );

  // Trigger the network start
  ZDApp_NetworkInit( extendedDelay );

  return ( networkStateNV );
}
**************************************
两种情况,编译了NV_RESTORE和未编译.见自启动模式记录的一些说明.灯节点没有编译NV_RESTORE因此networkStateNV == ZDO_INITDEV_NEW_NETWORK_STATE,调用ZDAppDetermineDeviceType():
**************************************
void ZDAppDetermineDeviceType( void )
{
 
  if ( zgDeviceLogicalType == ZG_DEVICETYPE_ENDDEVICE )
    return;

#if defined ( SOFT_START )
  if ( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR )
  {
    devStartMode = MODE_HARD;     // Start as a coordinator
    ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;
  }
  else
  {
    if ( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER )
    {
      softStartAllowCoord = FALSE;  // Don't allow coord to start
      continueJoining = TRUE;
    }
   
    devStartMode = MODE_JOIN;     // Assume joining
  }
#endif // SOFT_START
}
**************************************
灯节点编译过SOFT_START,且通过按K1设置了zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR,因而这里执行:
    devStartMode = MODE_HARD;     // Start as a coordinator
    ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;

然后跳回ZDOInitDevice()进入ZDApp_NetworkInit( extendedDelay )触发ZDAppTaskID的ZDO_NETWORK_INIT事件.看下对ZDO_NETWORK_INIT处理:
**************************************
UINT16 ZDApp_event_loop( byte task_id, UINT16 events )
{
  …………
  if ( events & ZDO_NETWORK_INIT )
  {
    // Initialize apps and start the network
    devState = DEV_INIT;
    ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
                     DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );

    // Return unprocessed events
    return (events ^ ZDO_NETWORK_INIT);
  }
  …………
}
**************************************
这里两个参数上面已经设置为:
    devStartMode = MODE_HARD;     // Start as a coordinator
    ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;
进入ZDO_StartDevice()
**************************************
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
  ZStatus_t ret;

  ret = ZUnsupportedMode;

#if defined(ZDO_COORDINATOR)
  if ( logicalType == NODETYPE_COORDINATOR )
  {
    if ( startMode == MODE_HARD )//MODE_HARD
    {
      devState = DEV_COORD_STARTING;//Started as Zigbee Coordinator
      //建网
      ret = NLME_NetworkFormationRequest( zgConfigPANID, zgDefaultChannelList,
                                          zgDefaultStartingScanDuration, beaconOrder,
                                          superframeOrder, false );
    }
    …………
**************************************
调用了NLME_NetworkFormationRequest()来建立网络.对NLME_NetworkFormationRequest()的调用会产生一个回调函ZDO_NetworkFormationConfirmCB()(参见主要函数说明3),接下来的回调函数流程与[Zigbee网络设备启动流程—协调器(自启动模式)]记录中的一样.
记录下最终应用层任务sapi_TaskID对ZDO_STATE_CHANGE事件的处理:
**************************************
UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )
{
   …………
        case ZDO_STATE_CHANGE: /*网络状态变化*/
          //作为网络设备成功开启,通知应用层
          // If the device has started up, notify the application
          if (pMsg->status == DEV_END_DEVICE ||
              pMsg->status == DEV_ROUTER ||
              pMsg->status == DEV_ZB_COORD )
          {
            SAPI_StartConfirm( ZB_SUCCESS );
          }
          else  if (pMsg->status == DEV_HOLD ||
                  pMsg->status == DEV_INIT)
          {
            SAPI_StartConfirm( ZB_INIT );
          }
          break;
  …………
}
**************************************
调用了SAPI_StartConfirm():
**************************************
void SAPI_StartConfirm( uint8 status )
{
#if defined ( MT_SAPI_CB_FUNC )
  /* First check if MT has subscribed for this callback. If so , pass it as
  a event to MonitorTest and return control to calling function after that */
  if ( SAPICB_CHECK( SPI_CB_SAPI_START_CNF ) )
  {
    zb_MTCallbackStartConfirm( status );
  }
  else
#endif  //MT_SAPI_CB_FUNC
  {
    zb_StartConfirm( status );
  }
}
**************************************
调用了zb_MTCallbackStartConfirm(),如果编译过MT_SAPI_CB_FUNC则也会调用zb_MTCallbackStartConfirm()通知MT.看下zb_StartConfirm()
**************************************
void zb_StartConfirm( uint8 status )
{
 // If the device sucessfully started, change state to running
  if ( status == ZB_SUCCESS )
  {
    myAppState = APP_START;
  }
  else
  {
    // Try again later with a delay
    osal_start_timerEx(sapi_TaskID, MY_START_EVT, myStartRetryDelay);
  }
}
**************************************
最终改变myAppState值来通知应用层网络设备启动成功.


3、协调器(非自启动模式HOLD_AUTO_START)—以SimpleApp的灯节点SimpleControllerEB按K1作为协调器启动为例.假设初始化成功,网络建立成功.
程序大致流程:
main()->osal_init_system()->osalInitTasks()->ZDApp_Init()->SAPI_Init()->触发sapi_TaskID的ZB_ENTRY_EVENT事件->等待按键->按K1写设备逻辑类型和启动选项到NV->zb_SystemReset()->main()->osal_init_system()->osalInitTasks()->ZDApp_Init()->SAPI_Init()->触发sapi_TaskID的ZB_ENTRY_EVENT事件->zb_StartRequest()->ZDOInitDevice()->ZDApp_NetworkInit()->触发ZDAppTaskID的ZDO_NETWORK_INIT->ZDO_StartDevice()->NLME_NetworkFormationRequest()->网络建立成功ZDO_NetworkFormationConfirmCB->触发ZDAppTaskID的ZDO_NETWORK_START->ZDApp_NetworkStartEvt()->触发ZDAppTaskID的ZDO_STATE_CHANGE_EVT->ZDO_UpdateNwkStatus()->触发sapi_TaskID的ZDO_STATE_CHANGE事件->SAPI_StartConfirm()->zb_StartConfirm()->设置myAppState = APP_START通知应用层网络设备开启成功,使再按K1时执行允许绑定功能.


***************************************
***************************************

说明:
1、本文为个人学习笔记,纯属个人理解,错误不可避免,仅供参考.随时更新
2、细节基本不管,遇到问题再作分析,程序注释为个人原始注释内容,记录有些仓促.   
3、欢迎交流,转载请注明出处,谢谢!

                                                                             2010.7.09  ~XF

  评论这张
转发至微博
0  分享到:        
阅读(401)| 评论(11)| 引用 (0) |举报
阅读(7073) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~