关于ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 终端节点入网以及绑定操作(一)

今天来看一下终端节点是如何加入网络,以及建立绑定操作并发送数据了。首先我们选择工作空间为SimpleSensorEB,好,我们先按一下S2键,因为在SAPI_Init中,我们利用RegisterForKeys( sapi_TaskID);注册了键盘消息,因此我们看一下在sapi如何对按键消息进行响应的。在UINT16 SAPI_ProcessEvent( bytetask_id, UINT16 events )中找到:

 

 case KEY_CHANGE:
#if ( SAPI_CB_FUNC )
         zb_HandleKeys( ((keyChange_t *)pMsg)->state,((keyChange_t *)pMsg)->keys );
#endif
         break;

 

好,接下来我们进入到zb_HandleKeys函数中看看源代码:

void zb_HandleKeys( uint8 shift, uint8 keys )
{
  uint8 startOptions;
  uint8 logicalType;

  // Shift is used to make each button/switchdual purpose.
  if ( shift )
  {
    if ( keys& HAL_KEY_SW_1 )
    {
    }
    if ( keys& HAL_KEY_SW_2 )
    {
    }
    if ( keys& HAL_KEY_SW_3 )
    {
    }
    if ( keys& HAL_KEY_SW_4 )
    {
    }
  }
  else
  {
    if ( keys& HAL_KEY_SW_1 )
    {
     if ( myAppState == APP_INIT )
     {
       // In the init state, keys are used to indicate the logicalmode.
       // The Sensor device is always an end-device
       logicalType = ZG_DEVICETYPE_ENDDEVICE;
       zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8),&logicalType);

       // Do more configuration if necessary and then restart device withauto-start bit set

       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();

     }
    }
    if ( keys& HAL_KEY_SW_2 )//成立
    {
     if ( myAppState == APP_INIT )//成立
     {
       logicalType = ZG_DEVICETYPE_ENDDEVICE;//修改本地设备类型为终端设备
       zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8),&logicalType);//将设备类型写入到flash中

       zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8),&startOptions );
       startOptions = ZCD_STARTOPT_AUTO_START;//修改启动选项
       zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8),&startOptions );//将启动选项写入到flash中
       zb_SystemReset();//系统重启
     }
    }

 

好,系统重启后,程序从头开始执行,在进行SAPI_Init函数的最后时,出现 osal_set_event(task_id,ZB_ENTRY_EVENT);因此,进入到进入事件处理函数当中。我们在SAPI_ProcessEvent函数里找到如下代码:

 

if ( events & ZB_ENTRY_EVENT )
  {
    uint8startOptions;

#if ( SAPI_CB_FUNC )  

   zb_HandleOsalEvent( ZB_ENTRY_EVENT );
#endif

    // LEDoff cancels HOLD_AUTO_START blink set in the stack
    HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);//首先关闭LED_4。

   zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8),&startOptions );//从flash中读出启动选项
    if (startOptions & ZCD_STARTOPT_AUTO_START)//条件成立
    {
     zb_StartRequest();//执行启动请求函数。
    }
    else
    {
     // blink leds and wait for external input to config andrestart
     HalLedBlink(HAL_LED_2, 0, 50, 500);
    }

    return(events ^ ZB_ENTRY_EVENT );
  }

 

继续到启动请求函数中去看一下源代码:

 

void zb_StartRequest()
{
  uint8 logicalType;

  zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE,sizeof(uint8), &logicalType );

 //以下代码主要是确认设备类型是否正确,可以判断if中的条件为0,执行else中的语句 

  if ((logicalType >ZG_DEVICETYPE_ENDDEVICE)     ||
#if !ZG_BUILD_ENDDEVICE_TYPE   //Only RTR or Coord possible.
     (logicalType ==ZG_DEVICETYPE_ENDDEVICE)    ||
#endif
#if!ZG_BUILD_RTR_TYPE        // Only End Device possible.
     (logicalType ==ZG_DEVICETYPE_ROUTER)       ||
     (logicalType ==ZG_DEVICETYPE_COORDINATOR)  ||
#elifZG_BUILD_RTRONLY_TYPE   // Only RTR possible.
     (logicalType ==ZG_DEVICETYPE_COORDINATOR)  ||
#elif !ZG_BUILD_JOINING_TYPE   //Only Coord possible.
     (logicalType ==ZG_DEVICETYPE_ROUTER)       ||
#endif
     (0))
  {
    logicalType= ZB_INVALID_PARAMETER;
   SAPI_SendCback(SAPICB_START_CNF, logicalType, 0);
  }
  else
  {
    logicalType= ZB_SUCCESS;//设置本地设备类型为ZB_SUCCESS
   ZDOInitDevice(zgStartDelay);//执行ZDO初始化设备函数。
  }
  return;
}

 

下面我们接着去初始化设备函数当中看一下源代码,可以找到:

 

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 beenupdated.
    zgInitItems(FALSE );  //初始化RAM item列表
  }

  ZDConfig_InitDescriptors();
  //devtag.071807.todo - fix this temporarysolution
  _NIB.CapabilityInfo =ZDO_Config_Node_Descriptor.CapabilityFlags;
 
  devState =DEV_INIT;    //Remove the Hold state

  // Initialize leave control logic
  ZDApp_LeaveCtrlInit(); //离开控制初始化

  // Check leave control reset settings
  ZDApp_LeaveCtrlStartup(&devState, &startDelay);//离开控制的一些设置

  // Leave may make the hold state comeback
  if ( devState == DEV_HOLD )
  {
    // Set theNV startup option to force a "new" join.
   zgWriteStartupOptions( ZG_STARTUP_SET,ZCD_STARTOPT_DEFAULT_NETWORK_STATE );

    // Notifythe applications
   osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
   
    return (ZDO_INITDEV_LEAVE_NOT_STARTED);   // Don't join - (onetime).
  }

#if defined ( NV_RESTORE )//编译不通过,并不是上电保留数据 模式
  // Get Keypad directly to see if a reset nv isneeded.
  // Hold down the SW_BYPASS_NV key (defined inOnBoard.h)
  // while booting to skip past NV Restore.
  if ( HalKeyRead() == SW_BYPASS_NV )
   networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
  else
  {
    // Determineif NV should be restored
   networkStateNV = ZDApp_ReadNetworkRestoreState();
  }

  if ( networkStateNV ==ZDO_INITDEV_RESTORED_NETWORK_STATE )
  {
   networkStateNV = ZDApp_RestoreNetworkState();
  }
  else
  {
    // Wipe outthe network state in NV
   NLME_InitNV();
   NLME_SetDefaultNV();
  }
#endif

  if ( networkStateNV ==ZDO_INITDEV_NEW_NETWORK_STATE )//成立
  {
   ZDAppDetermineDeviceType();

    // Onlydelay if joining network - not restoring network state
   extendedDelay = (uint16)((NWK_START_DELAY + startDelay)
             + (osal_rand() &EXTENDED_JOINING_RANDOM_MASK));
  }

  // Initialize the security for type ofdevice
  ZDApp_SecInit( networkStateNV); //初始化安全属性
  
  // Trigger the network start
  ZDApp_NetworkInit( extendedDelay);//开启网络初始化函数

  // set broadcast address mask to supportbroadcast filtering
  NLME_SetBroadcastFilter(ZDO_Config_Node_Descriptor.CapabilityFlags );
 
  return ( networkStateNV );
}

 

好,我们进入到网络初始化函数当中,看看终端节点如何进行网络初始化,在此之前我们看过的函数与协调器执行的函数没有什么区别,在这以后区别开始出现了。

 

void ZDApp_NetworkInit( uint16 delay )
{
  if ( delay )
  {
    // Waitawhile before starting the device
   osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay );
  }
  else
  {
   osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );//设置了一个网络初始化事件,在ZDO层的任务处理函数中处理。
  }
}


找到  UINT16 ZDApp_event_loop( uint8 task_id, UINT16events )中的:

 

if ( events & ZDO_NETWORK_INIT )
  {
    devState =DEV_INIT;//改变设备状态为初始化状态。
   
   ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType,devStartMode,
                    DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER);//开启设备函数,参数分别为设备类型,启动模式,信标帧,超帧.第一个参数是在初始化设备时调用初始化节点描述符函数里赋值的。
    return(events ^ ZDO_NETWORK_INIT);
  }

 

进入到启动设备函数中,看看源代码:

void ZDO_StartDevice( byte logicalType, devStartModes_tstartMode, byte beaconOrder, byte superframeOrder )
{
  ZStatus_t ret;
#if defined ( ZIGBEE_FREQ_AGILITY )
  static uint8 discRetries = 0;
#endif
#if defined ( ZIGBEE_COMMISSIONING )
  static uint8 scanCnt = 0;
#endif

  ret = ZUnsupportedMode;

  if ( ZG_BUILD_COORDINATOR_TYPE&& logicalType ==NODETYPE_COORDINATOR )//条件不通过,不是协调器
  {
    if (startMode == MODE_HARD )
    {
     devState = DEV_COORD_STARTING;
     ret = NLME_NetworkFormationRequest( zgConfigPANID,zgApsUseExtendedPANID, zgDefaultChannelList,
                                         zgDefaultStartingScanDuration, beaconOrder,
                                         superframeOrder, false );
    }
    else if (startMode == MODE_RESUME )
    {
     // Just start the coordinator
     devState = DEV_COORD_STARTING;
     ret = NLME_StartRouterRequest( beaconOrder, beaconOrder, false);
    }
    else
    {
#if defined( LCD_SUPPORTED )
     HalLcdWriteScreen( "StartDevice ERR", "MODE unknown" );
#endif
    }
  }

  if ( ZG_BUILD_JOINING_TYPE&& (logicalType == NODETYPE_ROUTER|| logicalType == NODETYPE_DEVICE) )//条件通过
  {
    if ((startMode == MODE_JOIN) || (startMode == MODE_REJOIN))//条件通过
    {
     devState = DEV_NWK_DISC; //将设备状态修改为网络发现状态

  #if defined( MANAGED_SCAN )
     ZDOManagedScan_Next();
     ret = NLME_NetworkDiscoveryRequest( managedScanChannelMask,BEACON_ORDER_15_MSEC );
  #else
     ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList,zgDefaultStartingScanDuration);//向网络层发送网络发现请求,交由网络层处理。怎么处理代码看不到。
    #if defined( ZIGBEE_FREQ_AGILITY )
     if ( !( ZDO_Config_Node_Descriptor.CapabilityFlags& CAPINFO_RCVR_ON_IDLE )&&
           ( ret == ZSuccess ) && (++discRetries == 4 ) )
     {
       // For devices with RxOnWhenIdle equals to FALSE, any networkchannel
       // change will not be recieved. On these devices or routers thathave
       // lost the network, an active scan shall be conducted on theDefault
       // Channel list using the extended PANID to find the network. Ifthe
       // extended PANID isn't found using the Default Channel list, anscan
       // should be completed using all channels.
       zgDefaultChannelList = MAX_CHANNELS_24GHZ;
     }
    #endif //ZIGBEE_FREQ_AGILITY
    #if defined( ZIGBEE_COMMISSIONING )
     if (startMode == MODE_REJOIN &&scanCnt++ >= 5 )
     {
       // When ApsUseExtendedPanID is commissioned to a non zero valuevia
       // application specific means, the device shall conduct an activescan
       // on the Default Channel list and join the PAN with the same
       // ExtendedPanID. If the PAN is not found, an scan should becompleted
       // on all channels.
       // When devices rejoin the network and the PAN is not foundfrom
       zgDefaultChannelList = MAX_CHANNELS_24GHZ;
     }
    #endif //ZIGBEE_COMMISSIONING
  #endif
    }
    else if (startMode == MODE_RESUME )
    {
     if ( logicalType == NODETYPE_ROUTER )
     {
       ZMacScanCnf_t scanCnf;
       devState = DEV_NWK_ORPHAN;

       
       scanCnf.hdr.Status = ZSUCCESS;
       scanCnf.ScanType = ZMAC_ORPHAN_SCAN;
       scanCnf.UnscannedChannels = 0;
       scanCnf.ResultListSize = 0;
       nwk_ScanJoiningOrphan(&scanCnf);

       ret = ZSuccess;
     }
     else
     {
       devState = DEV_NWK_ORPHAN;
       ret = NLME_OrphanJoinRequest( zgDefaultChannelList,
                                     zgDefaultStartingScanDuration );
     }
    }
    else
    {
#if defined( LCD_SUPPORTED )
     HalLcdWriteScreen( "StartDevice ERR", "MODE unknown" );
#endif
    }
  }

  if ( ret != ZSuccess )
   osal_start_timerEx(ZDAppTaskID, ZDO_NETWORK_INIT, NWK_RETRY_DELAY);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值