- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
zigbee端末经常掉线,什么原因呢?
掉线:一般都什么样的问题容易引起掉线呢?比如硬件,软件的那些方面呢?协议栈哪里呢?
重连:要说掉线不好分析,若能重连也可以。
1:设备掉线重连:
掉线后进入下面回调函数
void ZDO_SyncIndicationCB( uint8 type, uint16 shortAddr )
产生ZDO_NWK_JOIN_REQ
之后进入到
void ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr )
case ZDO_NWK_JOIN_REQ:
devStartMode = MODE_RESUME;//改为resume模式
2.设备断电后重新上电,直接就是resume模式
ZDApp_NetworkInit( 0 );//初始化网络
启动osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay );
进入到UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )
if ( events & ZDO_NETWORK_INIT )
devState = DEV_INIT;//初始化状态
ZDO_StartDevice();//开始入网
进入后执行最后一个else,以孤儿方式组网
devState = DEV_NWK_ORPHAN;
ret = NLME_OrphanJoinRequest( zgDefaultChannelList,
zgDefaultStartingScanDuration );
等待回调函数
void ZDO_JoinConfirmCB( uint16 PanId, ZStatus_t Status )
把结果通知ZDO_NWK_JOIN_IND
在此处void ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr )
case ZDO_NWK_JOIN_IND:
进入端末处理
ZDApp_ProcessNetworkJoin();
else if ( devState == DEV_NWK_ORPHAN || devState == DEV_NWK_REJOIN )
if (nwkStatus == ZSuccess)
devState = DEV_END_DEVICE;
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );////至此入网成功
否则失败了
else
{
if ( devStartMode == MODE_RESUME )、、、掉线后恢复网络失败后到此处
{
if ( ++retryCnt <= MAX_RESUME_RETRY )//////此处非常不明白为什么第一次执行后,就判断由resume改成rejoin模式呢?上面路由节点是3次后换模式
{
if ( _NIB.nwkPanId == 0xFFFF || _NIB.nwkPanId == INVALID_PAN_ID )
devStartMode = MODE_JOIN;
else
{
devStartMode = MODE_REJOIN;
_tmpRejoinState = true;
}
}
// Do a normal join to the network after certain times of rejoin retries
else if( AIB_apsUseInsecureJoin == true )///////此处改为join模式还能恢复到原来的网络了吗?
{
devStartMode = MODE_JOIN;
}
resume模式恢复网络失败后,清楚表后,重新执行网络初始化
// setup a retry for later...
ZDApp_NetworkInit( (uint16)(NWK_START_DELAY
+ (osal_rand()& EXTENDED_JOINING_RANDOM_MASK)) );
}
之后再次进入void ZDO_StartDevice()//再次加入网络
这次执行路由或者终端节点处理中的
if ( (startMode == MODE_JOIN) || (startMode == MODE_REJOIN) )//////上1次执行的else的resume模式
devState = DEV_NWK_DISC;
ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );////发现网络,这里具体是什么作用不是太清楚,开始模式为join和rejoin时,入网都要先执行NLME_NetworkDiscoveryRequest,进入case ZDO_NWK_DISC_CNF:尝试大于2次后再执行NLME_ReJoinRequest吗?为什么这样做呢?
等待回调函数
ZStatus_t ZDO_NetworkDiscoveryConfirmCB(uint8 status)
ZDApp_SendMsg( ZDO_NWK_DISC_CNF,)
进入处理消息
void ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr )
case ZDO_NWK_DISC_CNF:
若尝试大于2次
else if ( devStartMode == MODE_REJOIN )
{
devState = DEV_NWK_REJOIN;//////切换rejoin方式入网
if ( NLME_ReJoinRequest( ZDO_UseExtendedPANID, pChosenNwk->logicalChannel) != ZSuccess )
////////////////////以rejoin方式组网也是在ZDO_JoinConfirmCB等待入网的结果,成功则切换devState = DEV_END_DEVICE;osal_set_event( ZDAppTaskID, /////////////////////ZDO_STATE_CHANGE_EVT );失败则重新初始化网络
{
ZDApp_NetworkInit( (uint16)(NWK_START_DELAY
+ ((uint16)(osal_rand()& EXTENDED_JOINING_RANDOM_MASK))) );
}
为什么有些设备就是容易掉线,甚至有的失败执行上述重连过程也连不回来的,最坏的情况当协调器允许入网时候,这个设备竟然重新入网而不是恢复原来的网络,上述重连过程我理解的对吗?哪里可能有问题导致重连失败呢?上述过程都是协议栈原来的代码,我并没有进行修改。
抓包发现,重连的设备开始阶段都会发送orphan Notification,
若协调器相应了回复coordinator realignment,则非常大的概率就成功入网继续Device Announce
若协调器没有响应,则掉线设备恢复网络失败,此时设备是否应该重新发送呢?但上面程序中指执行一次NLME_OrphanJoinRequest,失败后if ( ++retryCnt <= MAX_RESUME_RETRY )切换模式rejoin了。而改为NLME_ReJoinRequest方式入网。
但抓包发现能恢复原来网络的大多是orphan Notification,之后协调器及时回复coordinator realignment的。发送rejoin是较少的。
掉线有个可能原因是INT_HEAP_LEN设置太小了,你的INT_HEAP_LEN是多大的?