Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1908355
  • 博文数量: 376
  • 博客积分: 2147
  • 博客等级: 大尉
  • 技术积分: 3642
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-06 10:47
文章分类

全部博文(376)

文章存档

2019年(3)

2017年(28)

2016年(15)

2015年(17)

2014年(182)

2013年(16)

2012年(115)

我的朋友

分类: 嵌入式

2014-06-28 18:15:46

     当控制节点上电后,首先经历一系列的初始化工作,最终在 sapi 层设置进入事件,然后通过任务事件处理函数对该事件进行处理,当读取 NV 的启动模式选项时,

zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

在编译选项中进行了设备,非自动启动模式,判断为非自动启动,因此看到控制节点的LED_2 闪烁,

HalLedBlink(HAL_LED_2, 0, 50, 500);

操作系统等待其他事件发生。

  当按下按键S1 后,由于在 sapi 层注册了按键事件,因此会发送 KEY_CHANGE 消息到sapi层,当收到 KEY_CHANGE 消息后,sapi 层的任务事件处理函数调用:

zb_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );

然后将设备逻辑类型(协调器)写入到 NV,并将自动启动模式写入到 NV

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

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

最后重新启动:

zb_SystemReset();

重新启动后,依然进入通过任务事件处理函数对进入事件进行处理,也就是 ZB_ENTRY_EVENT当读取 NV 的启动模式选项时,判断为自动启动,然后调用:

zb_StartRequest();

紧接着调用 ZDO层的初始化设备函数:

  ZDOInitDevice(zgStartDelay);

在该函数中设置了 NV 网络状态,并修改了当前设备状态:

networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;

devState = DEV_INIT;

最终触发网络初始化函数:

ZDApp_NetworkInit( extendedDelay );

设置网络初始化事件:

osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );

ZDO 层的任务事件处理函数对网络初始化事件进行处理,即启动该设备:

ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,

                      DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );

此时将改变设备状态为协调器启动:

devState = DEV_COORD_STARTING;

并根据设备逻辑类型和启动模式调用 NWK 层网络形成请求函数:

NLME_NetworkFormationRequest( zgConfigPANID, zgApsUseExtendedPANID,

zgDefaultChannelList, zgDefaultStartingScanDuration, beaconOrder, superframeOrder, false );

其中,个域网 ID号和默认通道号在f8wConfig.Cfg 中定义:

-DZDAPP_CONFIG_PAN_ID=0xFFFF  //PAN_ID

-DDEFAULT_CHANLIST=0x00000800  // 11 - 0x0B  信道号

NWK 层通过调用 MAC PHY 层相关功能函数执行一些列网络形成动作后,NWK

将接收到网络形成反馈,这里的很多网络层 MAC层的函数都不是开源的,可能会看不到源代码。即:

ZDO_NetworkFormationConfirmCB()

设置网络启动事件:

osal_set_event( ZDAppTaskID, ZDO_NETWORK_START );

ZDO 层任务事件处理函数将执行网络启动事件处理:

ZDApp_NetworkStartEvt();

此时将改变设备状态为协调器,并且保证电源供电:

devState = DEV_ZB_COORD;

osal_pwrmgr_device( PWRMGR_ALWAYS_ON );

而且设置 ZDO状态改变事件:

osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );

ZDO 层任务事件处理函数将执行 ZDO更新网络状态事件处理:

ZDO_UpdateNwkStatus( devState );

此时搜索端点列表,寻找曾经在 sapi 层注册过的端点号,并且将 ZDO 状态改变消息发送给这

些端点:

zdoSendStateChangeMsg(state, *(pItem->epDesc->task_id));

而且确定控制节点(此时为协调器)的 16 位网络地址和 64 IEEE 地址:

NLME_GetShortAddr();

NLME_GetExtAddr();   

sapi 层接收到ZDO状态改变消息后,sapi层的任务事件处理函数将进行处理:

SAPI_StartConfirm( ZB_SUCCESS );

最终将改变设备的应用状态为启动状态:

myAppState = APP_START;

至此,整个网络就建立起来了,现在等待节点的加入。

说明:

网络状态属性:

 

       typedef enum

{

  MODE_JOIN,         //设备为加入状态

  MODE_RESUME,    //设备为恢复状态

//MODE_SOFT,        // Not supported yet   还不支持

  MODE_HARD,       //设备为开始状态

  MODE_REJOIN     //设备为重新加入状态

} devStartModes_t;

 

设备状态属性:

 

typedef enum

{

  DEV_HOLD,                       //初始化-不会自动启动

  DEV_INIT,                        //初始化-没有连接到任何东西

  DEV_NWK_DISC,               //发现个域网去加入

  DEV_NWK_JOINING,           //加入一个个域网

  DEV_NWK_REJOIN,            // 重新加入个域网,只为终端设备

  DEV_END_DEVICE_UNAUTH,    // 加入了但是还不曾被信任中心验证

  DEV_END_DEVICE,            //验证后作为设备启动

  DEV_ROUTER,                //设备已经加入,已验证并且是一个路由器

  DEV_COORD_STARTING,       //作为Zigbee协调器启动

  DEV_ZB_COORD,              // 作为Zigbee协调器启动

  DEV_NWK_ORPHAN           //设备已经丢失它的父节点的信息

} devStates_t;


结束!

阅读(495) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~