搜索
查看: 14629|回复: 11

【深度分析Zigbee】第八讲:怎样实现入网操作

[复制链接]

9

主题

20

帖子

98

积分

注册会员

Rank: 2

积分
98
发表于 2014-1-15 16:09:58 | 显示全部楼层 |阅读模式
由于工作和搬家的原因,很长一段时间没有更新《Zstack协议栈初窥》系列文章了,在此向大家表达我深深的歉意。
这一期我将继续顺着Zstack协议栈初窥(六)的脉络,主要讲述Zigbee路由设备是如何完成入网操作的。
我们之前曾经提到过,所有zigbee的设备只有在完成入网过程后才能够接收来自网络中其它设备发送的无线信息,因此入网操作是Zstack协议栈中非要重要的一项功能。
Zigbee路由设备在首次上电后需要做的最重要的事情就是加入网络,我们下面就根据具体程序代码来一步步理清这个过程。同协调器一样,路由设备的具体执行流程也是:Main()->osal_init_system()->osalInitTasks()->ZDApp_Init()
ZDApp_Init首先检测SW1是否被按下,如果SW1被按下,设备将处于DEV_HOLD状态,不会进入组网状态,这里我们要特别注意。如果SW1没有被按下,那么程序将调用ZDOInitDevice来开启设备。
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;

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

  if( ZDO_INIT_HOLD_NWK_START != startDelay )
  {
    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 come back
    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).
    }

    // Trigger the network start
    ZDApp_NetworkInit( extendedDelay );
  }

  // set broadcast address mask to support broadcast filtering
  NLME_SetBroadcastFilter( ZDO_Config_Node_Descriptor.CapabilityFlags );

  return ( networkStateNV );
}
上面的这段代码我们在Zstack协议栈初窥(六)中也曾经贴出过,这里再次把它拿出来是要更细致地来分析它的作用。我们假设if ( HalKeyRead() == SW_BYPASS_NV )判断结果为false,那么networkStateNV的状态将取决于ZDApp_ReadNetworkRestoreState()的返回值。
uint8 ZDApp_ReadNetworkRestoreState( void )
{
  uint8 networkStateNV = ZDO_INITDEV_RESTORED_NETWORK_STATE;

  // Look for the New Network State option.
  if ( zgReadStartupOptions() & ZCD_STARTOPT_DEFAULT_NETWORK_STATE )
  {
    networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
  }

  return ( networkStateNV );
}
正常情况下,该返回值为ZDO_INITDEV_RESTORED_NETWORK_STATE。继续查看下面的代码,由于if ( networkStateNV == ZDO_INITDEV_RESTORED_NETWORK_STATE )trueZDApp_RestoreNetworkState()将被调用执行。
uint8 ZDApp_RestoreNetworkState( void )
{
  uint8 nvStat;
  // Initialize NWK NV items
  nvStat = NLME_InitNV();
  if ( nvStat != NV_OPER_FAILED )
  {
    if ( NLME_RestoreFromNV() )
    {
      // Are we a coordinator
      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 );
    }
    else
    {
      nvStat = NV_ITEM_UNINIT;
    }
    if ( ZG_SECURE_ENABLED )
    {
      nwkFrameCounterChanges = 0;
      if ( ZG_BUILD_COORDINATOR_TYPE && ZG_DEVICE_COORDINATOR_TYPE )
      {
        ZDApp_RestoreNwkKey();
      }
    }
    // The default for RxOnWhenIdle is true for Routers and false for end devices
    // [setup in the NLME_RestoreFromNV()].  Change it here if you want something
    // other than default.
  }

  if ( nvStat == ZSUCCESS )
    return ( ZDO_INITDEV_RESTORED_NETWORK_STATE );
  else
    return ( ZDO_INITDEV_NEW_NETWORK_STATE );
}
该函数负责从CC2530NV存储器中读取设备之前保存的网络数据信息。由于我们的路由设备是全新的没有入网过的,因此NLME_RestoreFromNV()的返回值为flasenvStat =将被赋值为NV_ITEM_UNINITZDApp_RestoreNetworkState()函数的返回值为ZDO_INITDEV_NEW_NETWORK_STATE;如果设备之前曾经加入过网络,并且在预编译选项中我们启用了NV_RESTORE,那么NLME_RestoreFromNV()的返回值为true,程序将通过NLME_GetShortAddr()等函数获取保存在NV中的网络地址、PANID等信息,ZDApp_RestoreNetworkState()函数的返回值将为ZDO_INITDEV_RESTORED_NETWORK_STATE   
未完待续。

本文为与非网月光码头原创,未经允许谢绝转载。
更多内容请见:【深度分析Zigbee】Zigbee技术知多少?资深大牛对对碰
----------------------------

主讲嘉宾简   介:网名:月光码头。毕业于中国科学院电子学研究所,主要从事zigbee物联网方向的应用研究,尤其擅长TI RF芯片、和Silicon Lab    MCU芯片的使用。现就职于上海理滋芯片设计公司,任研发部门经理,主要从事智能家居产品的设计开发,拥有5年多的zigbee软硬件开发经验。
------------------
推荐技术讲座:
  听东北人讲天线:每周一个实例,个个经典!(CST仿真实践全包括)
【ADS学习小组】课程汇总(火烽主讲)
【HFSS学习小组】课程汇总(木木主讲)
回复

使用道具 举报

84

主题

601

帖子

1903

积分

金牌会员

Rank: 6Rank: 6

积分
1903
发表于 2014-1-16 11:00:27 | 显示全部楼层

RE:【深度分析Zigbee】第八讲:怎样实现入网操作

终于回归了,期待已久
回复 支持 反对

使用道具 举报

0

主题

99

帖子

225

积分

中级会员

Rank: 3Rank: 3

积分
225
发表于 2014-1-22 14:15:08 | 显示全部楼层

RE:【深度分析Zigbee】第八讲:怎样实现入网操作

感谢楼主的精彩讲解,确实大有收获!
回复 支持 反对

使用道具 举报

6

主题

526

帖子

1688

积分

金牌会员

Rank: 6Rank: 6

积分
1688
发表于 2014-1-23 20:24:32 | 显示全部楼层

回复:【深度分析Zigbee】第八讲:怎样实现入网操作

终于等到了续集,谢谢啦
回复 支持 反对

使用道具 举报

0

主题

3

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2014-2-7 18:14:58 | 显示全部楼层

回复:【深度分析Zigbee】第八讲:怎样实现入网操作

从一看到八楼主写的很好,因为我刚学习CC2530的ZigBee还是有点迷惑和不知如何用在自己的工作中,特请前辈指教。比如我使用一个协调器需要高速的读取同时快速移动(每秒5米)的多个终端节点(100个),每个终端节点只要把自身的ID传给协调器就可,我需要使用TI提供的那个协议栈来完成呢。项目中还规定终端节点使用电池供电并可靠使用6个月以上才可更换。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2014-2-7 18:16:22 | 显示全部楼层

RE:【深度分析Zigbee】第八讲:怎样实现入网操作

从一看到八楼主写的很好,因为我刚学习CC2530的ZigBee还是有点迷惑和不知如何用在自己的工作中,特请前辈指教。比如我使用一个协调器需要高速的读取同时快速移动(每秒5米)的多个终端节点(100个),每个终端节点只要把自身的ID传给协调器就可,我需要使用TI提供的那个协议栈来完成呢。项目中还规定终端节点使用电池供电并可靠使用6个月以上才可更换。
回复 支持 反对

使用道具 举报

0

主题

33

帖子

50

积分

新手上路

Rank: 1

积分
50
发表于 2014-2-28 00:10:58 | 显示全部楼层

回复:【深度分析Zigbee】第八讲:怎样实现入网操作

我试过用Zigbee接RFID读写器,实现数据的无线传输,不错。
回复 支持 反对

使用道具 举报

0

主题

6

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2014-4-22 16:56:24 | 显示全部楼层

RE:【深度分析Zigbee】第八讲:怎样实现入网操作

谢谢分享
回复 支持 反对

使用道具 举报

0

主题

13

帖子

34

积分

新手上路

Rank: 1

积分
34
发表于 2014-5-22 14:50:44 | 显示全部楼层

RE:【深度分析Zigbee】第八讲:怎样实现入网操作

111111111111111
回复 支持 反对

使用道具 举报

0

主题

1

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2014-8-7 20:58:29 | 显示全部楼层
谢谢分享!求更新快一点
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

Archiver|手机版|小黑屋|RF技术社区

GMT+8, 2024-3-29 13:33 , Processed in 0.094111 second(s), 9 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表