【深度分析Zigbee】Zstack协议栈初窥(六):协调器的组网过程详解
来源:互联网 发布:linux 用户段错误 编辑:程序博客网 时间:2024/06/01 07:14
it()。进入到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 );
}
else
{
// Blink LED to indicate HOLD_START
HalLedBlink ( HAL_LED_4, 0, 50, 500 );
}
ZDApp_RegisterCBs();
}
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 );
}
在这个函数中有一段代码值得我们特别注意:
#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;
。。。
#endif
我们在以前的文章里曾提到过,设备在复位之后,之前的网络信息就会丢失,那么设备将以全新的状态组建或者加入到网络中,这在实际使用过程中非常不方便。很多的应用场景中都要求设备能够在复位后仍旧按照上次入网的状态重新连接到网络中,Zstack也提供了实现该机制的方法。在工程的Options->C/C++ Complier->Preprocessor的Defined symbols中我们填入:NV_RESTORE。再回到刚才说到的代码中,程序会调用HalKeyRead(),来判断SW5的状态。如果SW5没有被按下,程序会调用ZDApp_RestoreNetworkState,取出上一次保存在flash中的网络状态信息,设备将根据这些信息重新连接到网络中;如果SW5被按下,那么即便我们使用了NV_RESTORE,程序将调用NLME_InitNV()和NLME_SetDefaultNV(),清除之前保存的网络信息,然后以全新的状态加入网络中。在完成以上操作之后,程序会调用ZDApp_NetworkInit函数,触发ZDO_NETWORK_INIT事件。
void ZDApp_NetworkInit( uint16 delay )
{
if ( delay )
{
// Wait awhile before starting the device
osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay );
}
else
{
osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );
}
}- 【深度分析Zigbee】Zstack协议栈初窥(六):协调器的组网过程详解
- zigbee协议与开发-ZStack中之协调器数据包解析
- ZSTACK协调器掉电重新组网无法加入网络的解决
- ZigBee组网(原理分析)
- zigbee组网过程概述
- ZigBee组网过程
- zigbee组网过程
- zigbee组网过程浅析
- Zstack协议栈中CC2530协调器掉电重启后重新加入之前网络的方法
- Zstack协议栈中CC2530协调器掉电重启后重新加入之前网络的方法
- zigbee终端向多个协调器发起请求的思路(终端入网流程分析)
- ZigBee组网(代码级分析)
- ZigBee组网原理详解
- Zigbee学习(二)之Zstack协议栈运行原理分析
- ZigBee ZStack 协议栈学习--架构分析篇
- Zigbee协议栈ZStack构架(文件夹和协议栈各层的对应关系)
- Zigbee协议与开发 - 协调器/路由器节点(EB板)程序结构分析
- Zigbee协议栈ZStack构架
- ASP.NET的错误处理机制
- 今天天气
- C语言经典算法100例-结束语
- T4 生成实体和简单的CRUD操作
- VC 下加载 JPGJPEGGIFPNG 图片最简单的方法
- 【深度分析Zigbee】Zstack协议栈初窥(六):协调器的组网过程详解
- css 有用代码
- Modbus读写模拟量寄存器详解
- Android DecorView浅析
- UTF8到GB2312的用法
- 泛型使用
- 图像处理学习笔记一
- Jackson框架、json的各种转换输出、非常的IMBA
- SetFilePointer出现溢出的问题