Z-Stack协议栈有一个MAC定时器为操作系统提供计时。该定时器以每1ms为单位,更新系统的定时器事件链表。定时器事件链表如图5所示,链表的每一个结点记录了任务号(task_id),事件号(event_flag)与计时时间( timeout )和下一个结点地址(*next)。图中ZCL_OTA_MT_READn定义为每个请求节点对应的事件号,Response Spacing即为节点请求的响应间隔,把两者添加到链表当中。当计时时间减为0后,系统自动设定对应的事件号,从而使OTA服务器循环地向OTA应用控制台索取镜像块数据,并向节点发送镜像块响应。
以下是OTA服务器处理镜像页请求的部分代码段:
typedef struct
{
uint32 SeverfileOffset; //OTA服务器读取镜像的偏移量,与OTA客户端的同步
afAddrType_t Psourceaddress; //OTA客户端短地址
zclOTA_FileID_t FileID; //镜像信息,包括镜像类型,制造商ID与版本号
uint16 ResponseTime; //响应间隔时间
uint8 Length; //镜像块大小
uint8 Count; //镜像页计数
} zclOTA_Address_Index; //镜像页请求属性结构体
zclOTA_Address_Index Address_index[]; //镜像页请求属性结构体数组
if ( events & ZCL_OTA_MT_READn ) //处理OTA客户端镜像页请求事件
{
ZStatus_t status = ZFailure; //初始化状态值
Address_index[n].Count--; //自减镜像页计数变量
if(Address_index[n].SeverfileOffset 》= Imagesize) //判断镜像偏移量是否超出镜像大小
{
return ( events ^ ZCL_OTA_MT_READn ); //如果超出直接退出事件处理
}
//OTA服务器根据OTA客户端的镜像页请求信息,向应用控制台索取镜像块数据
Status = MT_OtaFileReadReq(&(Address_index[n].Psourceaddress), &(Address_index[n].FileID), Address_index[n].Length, Address_index[n].SeverfileOffset);
if (status == ZSuccess) //假如索取成功,累加已请求的镜像偏移量
{
Address_index[n].SeverfileOffset += Address_index[n].Length;
}
if(Address_index[n].Count 》 0) //判断累计的请求镜像块大小是否超出镜像页大小
{
//假如没超出,把该镜像页处理时间继续添加到定时器链表,等待下一轮的处理
osal_start_timerEx(zclOTA_TaskID, ZCL_OTA_MT_READn,Address_index[n].ResponseTime);
}
//结束处理事件,并清除该事件号
return ( events ^ ZCL_OTA_MT_READn );
}
4. 验证与分析
4. 1功能验证
为了验证OTA功能,在CC2530F256平台上搭建一个小型树状网络,并使用Packet Sniffer[13]对OTA更新时的节点进行抓包分析。如图6(a)所示,四个传感节点的当前固件并没有添加温度采集功能,所以温度显示为0;在新的固件中添加了温度采集函数,用于验证OTA更新成功。
对于某些特定应用,需要节点更新固件后能够保持原来的网络拓扑结构。内部Flash的NV区能够保存节点的网络信息,只要在工程添加NV_INIT与NV_RESTORE预编译项,节点在掉电后还能恢复原来网络信息。
对四个传感节点进行OTA更新。如图6(b)所示,OTA更新后,温度采集功能成功添加,而且传感节点的网络短地址没有发生变化,网络拓扑结构保持完整,验证了进行OTA镜像升级过程中,并不会对NV区进行擦除,有利于节点网络信息的恢复。
在OTA更新过程中,应用层的数据帧格式如图7所示。OTA服务器被配置为路由器(0x06BC),对传感节点(0x0002)进行点对点更新。第一条短帧是子路由向OTA服务器发送Image Block Request,应用层载荷从第4字节开始记录了新镜像的制造商ID(0x5678),镜像类型(0x1234),版本号(0x00000002)和镜像块偏移量。最后1个字节记录了每次传送最大镜像块大小(OTA_MAX_MTU),默认为0x20,即为32字节。第二条长帧是OTA服务器发送的Image Block Response,载荷记录格式与前者类似,并在最大镜像块大小字节后面附上32字节镜像块信息,从而完成一个镜像块传输周期。
评论
查看更多