运行中修改协调器PAN ID和Channel,协调器广播至所有的设备重启加入新建后的网络

从飞比论坛那边看到一个问题,记录下:

一个ZigBee网络运行中,协调器通过串口与上位机连接,上位机设置协调器的PAN ID和Channel,协调器收到配置信息后,

首先将PAN ID和Channel广播发送至网络中的所有节点,然后协调器自身重启,加入新网络。部分代码如下:
//PAN ID
uint16 panId = BUILD_UINT16(msg[LOCDONGLE_CONFIG_PANID_LO_IDX],
                                                 msg[LOCDONGLE_CONFIG_PANID_HI_IDX]);

//Channel
uint8 channelId = msg[LOCDONGLE_CONFIG_CHANNELID_IDX];
    
//更改pan id和channel
_NIB.nwkLogicalChannel = channelId;
_NIB.nwkPanId = panId;

NLME_UpdateNV(0x01);

//广播至所有节点
if(UpdateAllNetwork(panId, channelId) == afStatus_SUCCESS)
{

      //这里可以加入非阻塞的延时,一定不要加阻塞延时,否则无法执行其他的程序

SystemResetSoft();

}

static afStatus_t UpdateAllNetwork(uint16 panId, uint8 channelId)
{

  afAddrType_t dstAddr;
  uint8 dataLength = MSG_PANID_LENGTH + MSG_CHANNELID_LENGTH;
  uint8 *msg = osal_mem_alloc(dataLength);

  dstAddr.addrMode = (afAddrMode_t)afAddrBroadcast;
  dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
  dstAddr.endPoint = AF_BROADCAST_ENDPOINT;

  msg[0] = LO_UINT16(panId);
  msg[1] = HI_UINT16(panId);
  msg[2] = channelId;

  return AF_DataRequest(&dstAddr, 
                       (endPointDesc_t*)&epDesc, 
                       UPDATE_ALL_NETWORK,
                       dataLength, 
                       msg,
                       &LocDongle_TransID, 
                       0, 
                       AF_DEFAULT_RADIUS);
}
测试结果:当注释掉SystemResetSoft(),网络中的其他节点能够接受到广播,否则协调器重启组建新的网络,节点无法收到广播。
可能原因:协调器还没有将数据广播出去,协调器就重启了。

于是,我加了延迟函数,延迟几秒,但是问题依旧,DEBUG也是这个结果。无奈来询问各位,什么原因。此外,看看各位还有没有更好的实现方式,我觉得自己的方式不太自然。


解决方法:

我恰好也需要实现这个功能,已经实现了。
楼主问题分析的很对,确实是由于广播帧没有发送出去,协调器已经重启了,其他设备收不到重启命令。
但是解决的办法有点欠妥,Z-STACK发送数据是异步的,也就是AF_SENDDATA函数调用完成后并没有发送出去而是交给了下一层继续打包后最终才能发送出去,所以应该延时,但不能使用阻塞式的延时,停留在当前状态,会导致数据包没有发送出去。
我的解决办法是在AF_SENDDATA后,使用osal_start_timerEx定时器,定时器会在你设定的时间后,产生一个你设定的事件,然后去对应的事件中,重启协调器。我设定的事件是500ms!

你可能感兴趣的:(运行中修改协调器PAN ID和Channel,协调器广播至所有的设备重启加入新建后的网络)