zigbee 网络建立过程以及ZDO_STATE_CHANGE 在什么情况下被触发!

2024-11-03 04:20:11
推荐回答(2个)
回答(1):

  ZDO_STATE_CHANGE 只有当设备角色发生转变后才会触发,才能被告诉COOR你的网络中有一个设备变了角色。
  zigbee网络启动流程 ---- 协调器
  main()->osal_init_system()->osalInitTasks()->ZDApp_Init()
  进入ZDApp_Init()函数:
  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(); // Load the saveExtAddr pointer.
  // Check for manual "Hold Auto Start"
  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
  // Start the device?
  if ( devState != DEV_HOLD )
  {
  ZDOInitDevice( 0 );
  }
  else
  {
  // Blink LED to indicate HOLD_START
  HalLedBlink ( HAL_LED_4, 0, 50, 500 );
  }
  ZDApp_RegisterCBs();
  }
  协调器没有编译HOLD_AUTO_START,也没有手工设置SW_1,初始化devState = DEV_INIT(参见基本问题说明3).因此直接在ZDApp_Init()中进入ZDOInitDevice( 0 )开启设备.
  uint8 ZDOInitDevice( uint16 startDelay )
  {
  uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
  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.CapabilityFlags = ZDO_Config_Node_Descriptor.CapabilityFlags;
  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 )
  {
  // Set the NV startup option to force a "new" join.
  zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
  // Notify the applications
  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
  {
  // Determine if NV should be restored
  networkStateNV = ZDApp_ReadNetworkRestoreState();
  }
  if ( networkStateNV == ZDO_INITDEV_RESTORED_NETWORK_STATE )
  {
  networkStateNV = ZDApp_RestoreNetworkState();
  }
  else
  {
  // Wipe out the network state in NV
  NLME_InitNV();
  NLME_SetDefaultNV();
  // clear NWK key values
  ZDSecMgrClearNVKeyValues();
  }
  #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 );
  // Trigger the network start
  ZDApp_NetworkInit( extendedDelay );
  // set broadcast address mask to support broadcast filtering
  NLME_SetBroadcastFilter( ZDO_Config_Node_Descriptor.CapabilityFlags );
  return ( networkStateNV );
  }
  
  注:
  (1)自启动模式下SampleApp的终端和路由器总体流程基本一致、
  (2)以SampleApp为例,ZDO_StartDevice()函数的两个重要参数比较:
  终端:
  ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_DEVICE
  devStartMode = MODE_JOIN
  路由器:
  ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_ROUTER
  devStartMode = MODE_JOIN
  协调器:
  ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR
  devStartMode = MODE_HARD

回答(2):

ZDO_STATE_CHANGE 只有当设备角色发生转变后才会触发,才能被告诉COOR你的网络中有一个设备变了角色。