http://home.eeworld.com.cn/my/space-uid-361439-blogid-118534.html
在
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
的地方你可以自己实现一个重新入网的寻找过程,而不是复位整个硬件系统;
这个
network status
的变化
ED
是如何实现的呢?具体没有找到源码,但是我个人认为是在
ED poll
父节点要数据的时候得不到父节点的
ack
,就认为失去了联系,从而
network status
被改变了
本文来自论坛,点击查看完整帖子内容。