zigbee stack进阶
七、Saving Network Context/Application Data to Flash保存网络信息/程序数据到flash
本部分讨论把网络数据或程序产生的数据保存在不易丢失flash里而不是易丢失的RAM里.
1. Why Save Network Context and Application Data?
节点在突然掉电或者end device休眠的时候,可以将网络信息(比如网络地址,PANID,频道等)保留在flash里,避免重复加入网络。
The Jennic ZigBee stack allows the application to save the network context to Flash memory. This means that a device can survive a period of power-loss (such as a power failure or a device reset) without having to re-join the network.
For Routers and the Co-ordinator, the device will wake from a reset retaining all knowledge of any children it previously had, along with its parent’s address, radio channel and PAN ID. The Co-ordinator also retains any Binding table entries which previously existed. Since the Co-ordinator and Routers are normally mains-powered, the advantage of saving network context to Flash memory is that the devices can recover from a power failure.
On End Devices, which are normally battery-powered devices, saving network context to Flash allows the device to enter sleep mode without memory retention, and also allows the device to retain its context when the batteries are low or being replaced. An End Device retains its address, parent’s address, radio channel and PAN ID.
The same mechanism can also be used to store application data to Flash.
! Caution: If the application needs to store network context to Flash, it must not write directly to Flash memory itself.
2. When to Call vAppSaveContexts()
The function used to save network context and application data to Flash memory is vAppSaveContexts(). This function should be called by the application in the following four instances:
• The node has just successfully started/joined a network. This can be detected by
looking for the appropriate stack event in JZA_vStackEvent(). Calling
vAppSaveContexts() at this point saves the initial stack context, i.e. parent’s
address, radio channel, PAN ID
• When a new child has just joined, at a Router or the Co-ordinator
• When a new entry has been added to the Binding table on the Co-ordinator
• When a change has been made to any data which the application needs to store in Flash
along with the network context
3. Restoring Network Context and Application Data
节点会自动检查flash存储中是否有可用的网络信息,是否保存了程序数据,如果保存了,则在JZA_vStackEvent() 能够检测到事件JZS_EVENT_CONTEXT_RESTORED。
注意:在调用JZA_vStatStack启动stack的时候,会检查flash里是否存储了network context ,所以会在JZA_vStackEvent() 里能够看到存储状态。
第一次调用JZA_AppEventHandler()的时候,网络信息和程序数据就已经存储了。
4.如何向flash存储网络信息
如果一个节点不需要为其他节点提供绑定服务,可以用下面的程序,使用stackevent处理。
对于coordinator提供绑定服务的话,使用下面程序,使用eventhandler处理
5.向flash存储网络信息的同时存储程序数据
vAppSaveContexts()也可以用来存储程序数据,结构体JZS_sConfig有两个成员分别是指向数据的指针和数据长度,
指向数据的指针必须在stack启动之前就要设定好,比如在程序AppColdStart()里设定,
比如,可以定义一个数组,然后将上面的指针设定为数组名。
然后,当stack检查flash存储数据的时候,就会把修正的数据以及数据长度写进去。
6.向flash只存储程序数据
如果只想存储数据,而不向存储网路信息,那么可以使用Integrated Peripherals API里的标准flash函数。 可参考Integrated Peripherals API Reference Manual(JN-RM-2001).
In this case, however, it is necessary that the first byte of Flash
memory is set to 0xFF. This is because the ZigBee stack checks this location on
waking, and uses it to determine whether a valid network context has been stored. A
value of 0xFF means no context has been saved, so the stack will proceed to start
with a new stack context.
7.Sleep with Memory Held without Valid Context
略
八、侦查通信丢失Detecting Communications Loss
1.通信丢失
动态网状拓扑中,Co-ordinator and Routers,如果路由中的下一跳节点失败了,或者超出通信范围了, Co-ordinator and Routers会尝试一下两种方法中的一种:
修复已经存在的路由或者,
新建一个路由.
当然,如果Co-ordinator and Router移除与所有其他节点的通信范围,则上面的尝试会失败,当重回通信范围的时候,会接着尝试连接,这些不需要在应用程序中操作。
On an End Device, since all communications go through the parent, if the parent has
failed or is out of range, the End Device will be unable to send or receive any frames
at all. It is the responsibility of the application to detect this situation. In this case, it
can either periodically re-try the send (in which case, upon moving back into range
of its parent, the message send will succeed) or attempt to find a new parent
2.end device侦查是否丢失父节点
一个end device可以通过 监视应用程序支持子层的状态确认信息(通过afdeDataRequest()获得),获知是否失去父节点。然后作为JZA_vStackEvent() 里的stack event传给应用程序,事件的eEventId 设置为JZS_EVENT_APS_DATA_CONFIRM。
This is passed to the application as a stack event in JZA_vStackEvent() with the parameter eEventId set to JZS_EVENT_APS_DATA_CONFIRM.
返回的状态如果是MAC_ENUM_SUCCESS ,表明frame已经成功传到MAC层,然后传到了父节点。
如果返回的状态是MAC_ENUM_NO_ACK,表明end device没有收到父节点的确认帧acknowledgement frame。
如果这个事件连续多次发生,那么end device就需要找一个新的父节点了。
3.强制end device找新的父节点
end device丢失父节点之后,寻找新的父节点的最简单的方式是,擦除flash里的网路信息,然后执行软重启。
bAHI_FlashErase();
JZS_vSwReset();
Note: The function JZS_vSwReset() should be used rather than vAHI_SwReset(), as this ensures that the IEEE 802.15.4 PHY is idle before performing the reset.
If End Devices move parents too many times, the End Device capacity of all the parents will become exhausted and End Devices will no longer be able to associate with new parents, or even with their old parents.更换父节点的次数有限次。
4.网络地址重用
如果不断有子节点超出通信范围,那么父节点的网络地址会被耗尽,然后父节点会清除Association Permit flag,使新的节点无法加入网路,即使是router。
zigbee协议里没有地址重用机制,jennic添加了这种机制:父节点如果发现end device子节点一段时间内不向自己发消息,就认为子节点失效或超出通信范围,然后就将子节点从邻居列表里移除,对应的地址可以重新使用。
同时end device需要周期性的向父节点发送空包,通知父节点自己任然还在。
要实现地址重用功能,程序可以调用一个函数使end device 的地址重用:
PUBLIC void JZS_vEnableEDAddrReuse(uint16 u16CommsLossPeriod);
u16CommsLossPeriod是超时时间,然后,如果end device在u16CommsLossPeriod 秒内没有过发送帧,父节点会 将子节点从邻居列表里移除,对应的地址可以重新使用。
每次移除一个end device,回调函数JZA_vStackEvent()就会产生一个stack event,eEventId set to:
JZS_EVENT_INACTIVE_ED_DELETED
被移除的节点的地址存储在
puStackEvent->sInactiveEDDeletedEvent.u16Addr
The function JZS_vEnableEDAddrReuse() and associated software entities are
described in the Jennic ZigBee Application Development API Reference Manual
(JN-RM-2014).