查看: 46453|回复: 25

End device 节点失去父节点的重新入网处理办法

[复制链接]
kennan 发表于 2012-8-12 22:03:39 | 显示全部楼层 |阅读模式
在TI的Zstack协议栈中,End Device(ED)在失去父节点的时候就不会重新入网了,那么我们该如何处理才能够让ED重新入网呢?我所能想到的办法有以下几种:
1、        入网之后,通过网络管理相关函数获取父节点短地址,然后定时同父节点进行数据交互,即很多人称之为心跳数据包的方式,如果ED长时间得不到父节点的ACK,那么就复位自己,方法是调用OnBoard.h中的宏函数SystemReset()。该函数的实现是通过禁止中断,然后写看门狗,之后死等看门狗复位,具体可以去看协议栈相关代码。
2、        有TI原装开发板的同学(带LCD的),可能会发现在ED节点上加装LCD后,如果协调器被关掉了,那么会在LCD上显示Assoc Cnf fail,这说明在我们不人为为ED和其父节点增加心跳包的条件下,网络间一定是在不停地进行着某种信息的交换。那么我们看看Assoc Cnf fail是哪里来的,用source insight之类的代码阅读工具找一下Assoc Cnf fail,我们会发现它出现在Nwk_globals.c里面,即:
#if defined ( LCD_SUPPORTED )
  const char PingStr[]         = "Ping Rcvd from";
  const char AssocCnfStr[]     = "Assoc Cnf";
  const char SuccessStr[]      = "Success";
  const char EndDeviceStr[]    = "EndDevice:";
  const char ParentStr[]       = "Parent:";
  const char ZigbeeCoordStr[]  = "ZigBee Coord";
  const char NetworkIDStr[]    = "Network ID:";
  const char RouterStr[]       = "Router:";
  const char OrphanRspStr[]    = "Orphan Response";
  const char SentStr[]         = "Sent";
  const char FailedStr[]       = "Failed";
  const char AssocRspFailStr[] = "Assoc Rsp fail";
  const char AssocIndStr[]     = "Assoc Ind";
  const char AssocCnfFailStr[] = "Assoc Cnf fail";
  const char EnergyLevelStr[]  = "Energy Level";
  const char ScanFailedStr[]   = "Scan Failed";
#endif
我们再找一下AssocCnfFailStr,他出现在Nwk_globals.c里面的一个函数nwk_Status(),该函数的说明指出它的功能是status report,也就是报告状态的。该函数中的:
case NWK_ERROR_ASSOC_CNF_DENIED:位置里面是把AssocCnfFailStr字符串写到LCD上的函数。
如果能够看看那个函数调用了nwk_Status()该多好,可惜,调用部分被TI和谐掉了。更深层次的理解没法子了,但是不影响我们的最终目标。
也就是说如果能够在AssocCnfFailStr被写到LCD上的地方软件复位CC2530就行了。那么好,我们添加一个软件复位函数在这里。这个软件复位函数有现成的可用,即OnBoard.h中的那个SystemReset()。
再多做点儿工作,如果你的ED没有LCD,那么编译的时候就不能选择LCD_SUPPORT了,nwk_Status()函数的主实现也没办法执行了。怎么办?为了不破坏协议栈原来代码,我们可以用编译选项来控制一下。即在该函数开始之初添加:
#if defined (MY_BOARD)
switch(statusCode)
{
   case NWK_ERROR_ASSOC_CNF_DENIED:
      SystemReset();
      break;
default:break;   
}
#endif
这样就好了,在编译器compiler的预编译选项中添加MY_BOARD,但是不要LCD_SUPPORT,可以了。
采用上面方法,可以在ED失去同父节点联系的时候自动复位ED了。

讨论:
1、        如果你不想在失去联系的时候复位整个CC2530系统,可能系统上带着其它硬件设备,不能乱复位,那么在调用SystemReset的地方你可以自己实现一个重新入网的寻找过程,而不是复位整个硬件系统;
2、        这个network status的变化ED是如何实现的呢?具体没有找到源码,但是我个人认为是在ED poll父节点要数据的时候得不到父节点的ack,就认为失去了联系,从而network status 被改变了。
outman 发表于 2012-8-13 22:28:25 | 显示全部楼层
毛毛老师,又有新作,赶紧顶起来
Vigi_Lin 发表于 2012-8-15 09:09:23 | 显示全部楼层
这不失为一个好方法
pisces 发表于 2012-8-16 13:02:26 | 显示全部楼层
又受教了.....
bkrclp 发表于 2012-8-16 21:47:26 | 显示全部楼层
我做了几个cc2530的板子想组网,但发现组网不稳定,ED经常离开网络,一会又从新加入网络,不知道是不是这个原因。
神经火光 发表于 2012-8-16 21:56:29 | 显示全部楼层
我用SerialAPP组星形网,发现第一次组网成功后,发送数据,协调器会立即接收,但是,把enddevice断开后重连,在传数据,会有等待时间,第一次等待10ms,第二次20ms,第三次30ms左右,怎么回事?能给点建议不?
kings316 发表于 2012-8-18 21:22:56 | 显示全部楼层
网络类型怎么选择的啊? 星型什么的型的?
doorsoasis 发表于 2012-8-21 09:23:01 | 显示全部楼层
毛毛老师分析的很透彻
但我有个疑问,如果ED丢失了父设备的信息,感觉应该会走ZDO的同步丢失流程。
void ZDO_SyncIndicationCB( uint8 type, uint16 shortAddr )
然后又会走个循环重新的REJOIN过程,应该是会重新REJOIN的啊,除非用户自己去修改入网机制。默认的协议栈应该是永久寻网的。
而且如果想让设备重新寻网,可以直接调用
ZDApp_NetworkInit( uint16 delay ) 来让设备去搜寻网络。复位的话其实也可以。不过那样的话如果一直没有网络 设备就一直在复位了
 楼主| kennan 发表于 2012-8-22 11:18:16 | 显示全部楼层
ZDO_SyncIndicationCB,这个函数我试过,掉网没反应哦
tiantangzai 发表于 2012-8-22 15:50:25 | 显示全部楼层
我现在纠结了,我继续搞780MHz的有没有可持续发展的可能
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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