协议栈的网络初始化主要是在ZDApp.c里面做的,如果未设置DEV_HOLD,设备会自动循环初始化网络,直到加入网络
如下
ZDApp_Init()--> ZDOInitDevice( 0 )-->ZDApp_NetworkInit()(在此函数里面启动ZDO层事件ZDO_NETWORK_INIT)。
UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )
{
……
if ( events & ZDO_NETWORK_INIT )
{
// Initialize apps and start the network
devState = DEV_INIT;
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );//更新设备网络状态,并将状态传递到应用层,用户接收到数据后就可以根据设备状态进行相应的处理(即
UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )
{case ZDO_STATE_CHANGE:
// If the device has started up, notify the application
if (pMsg->status == DEV_END_DEVICE ||
pMsg->status == DEV_ROUTER ||
pMsg->status == DEV_ZB_COORD )
{
SAPI_StartConfirm( ZB_SUCCESS );
}
else if (pMsg->status == DEV_HOLD ||
pMsg->status == DEV_INIT)
{
SAPI_StartConfirm( ZB_INIT );
}
break;
}
)
ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );
// Return unprocessed events
return (events ^ ZDO_NETWORK_INIT);
}
……
}
ZDO_StartDevice()函数会触发ZDO层事件SYS_EVENT_MSG,从而调用函数SAPI_ProcessZDOMsgs(),如下
UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )
{
case ZDO_CB_MSG:
SAPI_ProcessZDOMsgs( (zdoIncomingMsg_t *)pMsg );//此函数会根据设备网络状态再次启动ZDO事件ZDO_NETWORK_INIT,这样就形成了循环,直到加入网络
break;
}
问题:继续深入应用层关于ZDO_STATE_CHANGE的处理可以发现,在加网不成功后,又一次对设备进行了初始化,这样不就与ZDO层的网络流程重复了吗。
void zb_StartConfirm( uint8 status )
{
if ( status == ZB_SUCCESS )
{
myAppState = APP_START;
// Set event to bind to a collector
osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT, myBindRetryDelay );
}
else
{
// Try joining again later with a delay
osal_start_timerEx( sapi_TaskID, MY_START_EVT, myStartRetryDelay );
}
}
void zb_HandleOsalEvent( uint16 event )
{
uint8 pData[2];
if ( event & MY_START_EVT )
{
zb_StartRequest();
}
额,忽然间明白了。我研究过的这个流程。应用层关于加网失败的处理,是针对 pMsg->status为DEV_INIT或DEV_HOLD时的处理,而在不配置DEV_HOLD的情况下,ZDO层传递过来的参数一般是DEV_NWK_DISC,所以应用层并没有处理,也就不存在重复加网的问题了。
总结:我2了。
看不懂的更2了………………
选择购线,构造安全,连接你我!http://www.gooxian.com/
我已经贴的很详细了,你可能没看例程,所以有点不明白,对照例程就很好理解了