MEMS/传感技术
无线传感网络是由大量体积小,供电资源有限,并配置一定计算能力和无线通讯能力的传感节点组成。对于传感网络系统,一定存在程序代码更新和维护的需求,但由于传感节点分散部署的特点,使得网络远程节点的程序升级变得异常困难。为此,空中下载(over the air, OTA)提供了一种有效的更新手段。本文首先介绍基于 ZigBee协议的OTA系统,并在CC2530F256 硬件平台作出验证。最后,在Z-Stack协议栈中,设计出一种镜像页请求的OTA更新方式,并通过实验测试,与原有的镜像块请求方式进行了比较分析。实验结果表明,镜像页请求方式可以大大减少网络的更新流量,从而提高节点的更新效率。
引言
近年来,由于硬件成本的下降以及制造工艺的进步,无线传感网络技术逐步取得大规模商业应用,如医疗监控,智能电网和智能家居[1]。对于任何一个嵌入式计算机系统,都存在程序代码升级的需要。在无线传感网络的应用环境中,由于大量节点分散性部署,节点的回收工作变得异常困难,使传统的物理连接的程序更新手段不再适用。对此,一种有效的解决方案是OTA技术。
空中下载技术起源于移动电话网络,能够通过移动通信网络(如GSM)对SIM卡数据进行远程管理与更新[2]。借鉴于移动通信网络,空中下载技术也能应用于无线传感网络。与网络层的路由协议[3]不同,代码分发协议[4]是支撑OTA的核心技术。前者关注的是如何迅速高效地中转网络中的数据信息,后者关注的是如何向各节点完整无误地传递更新代码[5]。目前,成熟的代码分发协议已经提出,典型的如基于TinyOS系统的Xnp[6]与Deluge[7],前者提出了单跳网络的更新方案,后者支持多跳网络更新功能,但都需要具体的硬件平台支持。
本文移植并验证了一种基于ZigBee协议[8]的空中下载技术,其分发协议支持点对多传输更新功能,多跳网络的代码分发功能由路由协议支撑。在Z-Stack协议栈[9]下,仅仅支持镜像块请求功能,更新效率并不理想。针对此问题,设计出一种高效的镜像页请求功能,能够提高点对多的传输更新效率,并减少网络流量。
1. OTA概述
ZigBee协议规范使用了IEEE 802.15.4定义的物理层(PHY)和媒体介质访问层(MAC),并在此基础上定义了网络层(NWK)应用层(APL)。针对无线传感网络重编程技术的需求,ZigBee联盟在原有协议的框架上,提出了一种OTA规范[10],作为一个系统可选的功能模块。
图1为OTA系统的结构示意图,整个系统主要由3部分构成:OTA应用控制台,OTA服务器,OTA客户端。其中OTA应用控制台是上位机管理软件,负责OTA镜像管理,网络节点信息陈列与发送更新命令;OTA服务器负责向远程节点无线发送升级镜像,并通过串口与上位机连接,向应用控制台汇报各节点更新进度信息等;OTA客户端是指远程网络中的待升级节点。
根据代码的更新范围,分为整体代码更新与基于差异性的更新[11]。前者是把所有可执行的二进制代码打包成一个镜像分发给节点,后者是通过比较新旧镜像文件之间的差异,产生一个编辑脚本,然后把这个脚本分发到网络中的节点进行差异性更新。毫无疑问,前者需要传输的数据量较大,一般为上千字节级,增加了网络负担,但代码更新操作相对简单;后者发送的数据量虽少,但增加了更新过程的复杂度,对处理器产生更大的负担,带来较大的能源损耗。由于ZigBee协议对网络节点的低功耗标准有严格的要求,其OTA代码分发协议采用前者的镜像传输方式。
服务器与客户端之间的数据交互过程如图2所示。首先OTA服务器通过单播或者广播方式向OTA客户端(节点)发送镜像公告(Image Notify),指示新镜像已经准备好。收到镜像提示信息后,节点就向OTA服务器发送查询下一个镜像请求(Query Next Image Request),此请求信息包含了当前运行固件的版本信息。收到该请求后,OTA服务器作出响应(Query Next Image Response)。随后,OTA客户端与OTA服务器通过二次握手机制,镜像块请求(Image Block Request)和镜像块响应(Image Block Response),完成整个镜像传输过程。当OTA客户端收到镜像块数据后,把块数据写到第二存储区(客户端当前运行的镜像保存在第一存储区)。完成下载后,节点将对下载后的镜像进行CRC校验。最后,当节点需要更新时,把新镜像从第二存储区复制到第一存储区,新固件开始运行,从而完成了整个升级过程。
2. OTA系统设计
本文的OTA系统基于TI公司的ZigBee SOC芯片CC2530F256[12]设计,包括硬件与软件的设计。其中硬件部分主要涉及CC2530 F256内部Flash存储空间分配方式与镜像存储方式的选择;软件部分介绍了OTA启动代码工作流程。
2. 1硬件系统
CC2530F256内部集成一个增强型8051单片机,拥有8KB SRAM和256KB内部flash存储器。内部flash主要用来保存程序代码和常量数据。由于传统8051 代码存储空间寻址范围只有64KB,CC2530把内部256KB flash分成8个bank,每一个bank大小是32KB,通过寄存器FMAP.MAP[2:0]选择不同的bank映射到代码存储空间,解决了寻址空间受限的问题。
对于OTA客户端,启动代码位于bank0的0x0000到0x0800地址区域,大小为2KB。其余的254KB的flash空间,用来存储当前固件和其他信息。值得注意的是,0x0888~0x088B区域存放了CRC校验信息,0x088C~0x0897区域存放了PREAMBLE,即镜像大小,制造商ID,镜像类型和镜像版本号信息。另外,bank7最后的14KB空间(0x7C800~0x7FFFF)用作非易失性(None volatile, NV)变量区(12KB)和特定信息保留区(2KB)。
OTA系统升级方案有两种,分别是片内flash升级和片外flash升级。片内flash的方案是把256KB的flash大小分成两半,前一半(第一存储区)提供给当前运行镜像存储,后一半(第二存储区)提供给新镜像存储;片外flash的方案是把片内flash作为第一存储区,外扩的flash作为第二存储区。考虑到一般程序固件大小都超过128KB,和以后程序功能升级的扩展性,本文采用片外flash的方案。采用的片外flash(M25PE20)容量为256KB,通过SPI总线与CC2530之间传输数据。
2. 2软件系统
对于基于任务事件轮询机制的Z-Stack工程,默认是没有添加OTA功能。如果节点需要开启OTA功能,首先需要烧写OTA的启动代码。当节点完成镜像接收之后,对新镜像进行CRC校验,并清空当前镜像的CRC信息,然后重启。当节点重启后,首先跳转到启动代
码的地址,开始执行如图3所示的工作流程。由于内部镜像的CRC信息被清空,所以被判断为不正确而执行下一步。由于为0的CRC信息标志着不需要被重新校验,故执行将新镜像复制到片内Flash的操作,并产生新镜像的CRC信息。然后,重新执行启动代码。新镜像启动时读取其CRC信息,再次判断后跳转到应用程序区,完成整个启动过程。
3. OTA的镜像页请求实现
根据ZigBee OTA的规范,OTA客户端向OTA服务器请求镜像的方式有两种,分别是镜像块请求与镜像页请求。前者是基于二次握手机制,镜像块请求包含了已下载镜像的偏移量(File offset)与每次传输的镜像块大小等信息。当OTA服务器接收到该请求后,根据请求节点的短地址,镜像偏移量和镜像块大小等信息,通过串口向OTA应用控制台索取特定的镜像块。随后,OTA服务器回复的镜像块响应包含了该镜像块数据。当节点收到镜像块数据后,把块数据写到第二存储区,随即更新下载镜像的偏移量,并准备下一轮的请求。
镜像块请求的优点是能够通过二次握手机制,确保每次传输的镜像块数据准确无误。但是大量的请求信息,无疑给整个网络的流量造成了严重的负担。再者,节点不停地发送请求命令,也加剧了自身的能源损耗。在外界干扰并不严重或点对点传输的应用场合,节点与服务器交换数据的过程并不会出现大量的丢包现象,基于块请求的OTA更新方式效率较低。于是需要设计出一种能够减轻网络流量,提高效率的更新手段。
镜像块请求功能在大部分的ZigBee开发平台上(如TI的Z-Stack协议栈)已得到实现,但并没有提供镜像页请求功能。本文根据ZigBee OTA的规范,在Z-Stack协议栈上设计出镜像页请求的更新方式。页请求命令与块请求命令类似,在数据帧当中附加了镜像页大小(Page Size)与响应间隔(Response Spacing)信息。当OTA服务器收到一次页请求后,在一定时间间隔内,多次向节点发送块响应,免去了多次块请求。其中块响应的次数由镜像页大小决定,时间间隔由响应间隔设定。正因为请求命令的锐减,能够大大减轻整个网络流量的负担,并提高节点的传输更新效率。
Z-Stack运行在一个OSAL操作系统上,OSAL是一种基于任务事件调度机制的操作系统。每个任务包含若干事件,每个事件对应一个事件号。当一个事件需要产生时,可以通过API函数设置相应的事件号,然后提交给操作系统调度触发。本文设计的镜像页请求功能正是基于这种机制。如图4所示,OTA服务器为每一个请求更新的节点分配一个事件号,并通过请求节点的短地址索引,设置特定的事件。进入事件后,OTA服务器通过串口向OTA应用控制台请求镜像数据块,并向节点发送镜像块数据。通过把事件添加到定时器链表,就能够以响应间隔为时间单位,循环发送镜像块数据,直到累计的发送镜像块大小等于节点的请求镜像页大小,从而完成一次镜像页请求的传输过程。
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字节镜像块信息,从而完成一个镜像块传输周期。
4. 2效率分析
搭建一个星形网络,把OTA服务器配置成协调器,把所有OTA客户端配置成节点,并进行如下两个实验。
实验一(测试数据如表1、表2所示):为了对比分析两种更新手段的效率,分别使用镜像块请求命令与镜像页请求命令,对节点进行OTA更新。星形网络中,通过广播Image Notify,能够对多节点进行批量更新。网络规模分别为1个节点到6个节点,测量了不同规模网络下节点完成更新传输所需的时间。Min与Max分别指最快与最慢完成更新传输的节点对应的时间,Ave指平均每个节点完成更新传输所需时间(使用Max值计算)。其中镜像页请求设置的Response Spacing为100ms,Page size为640字节。镜像大小统一为113K字节,并修改OTA_MAX_MTU大小为64字节。节点与OTA服务器间隔均为5米。
表1 镜像块请求的传输时间(响应间隔= 100ms)
网络节点数123456
Min. Time/s207.2209.3214.4217.5221.4230.0
Max. Time/s207.2209.3214.4217.5222.9231.7
Ave. Time/s207.2104.771.554.444.638.6
表2 镜像页请求的传输时间(响应间隔= 100ms)
网络节点数123456
Min. Time/s179.6108.1180.6181.3182.6184.0
Max. Time/s179.6180.1180.6181.3184.7193.0
Ave. Time/s179.690.160.245.336.932.7
实验二(测试数据如表3所示):为了测试镜像页请求在点对点更新情况下的最高效率,设定最短的Response Spacing为10ms,分别测量不同Page Size下的单个节点更新传输时间。使用CC2531(支持USB)作为OTA服务器,能够缩短服务器向应用控制台索取镜像块数据的时间,进一步加快更新传输效率。镜像大小统一为113K字节,OTA_MAX_MTU大小为64字节,节点与OTA服务器间隔均为5米。
表3 不同镜像页大小下的传输时间(Response Spacing = 10ms)
Page Size/byte64
(1)128
(1/2)192
(1/3)256
(1/4)320
(1/5)640
(1/10)1024
(1/16)3200
(1/50)6400
(1/100)
Time/s77.253.746.243.436.431.529.928.327.3
实验一中,使用镜像块请求,节点发送镜像块请求所需时间为15.5ms,OTA服务器返回镜像块响应所需时间实际为96ms左右,来回确认帧时间大概为1.92+3.84=5.76ms。一个更新周期传输镜像块大小为64字节,完成113K字节大小的镜像传送需要1765个周期。总时间为(96+15.5+5.76)*1765=206963ms,这与表1测量值207.2基本符合。本文设计的镜像页请求,镜像页大小为640字节,每次传输镜像块大小为64字节,即节点发送1次页请求可以得到10次块响应。当更新1个节点时,使用镜像页请求可以把原来的1765条请求命令和1765条确认帧减少十分之九,共减少3177条传输帧。减少的传输帧数量随着节点数目成比例增长。对比表1与表2,可以发现无论节点数目为多少,页请求的平均每个节点的更新传输时间都比块请求的要短。其中发送镜像页请求时间为15.5ms,请求确认帧时间为1.92ms,节点为1时,共减少时间为(15.5+1.92)*1765*0.9=27672ms,此值与表1表2的测量值207.2-179.6=27.6s基本符合。
实验二中,由于采用了支持USB的CC2531,能够把OTA服务器返回的镜像块响应所需时间缩短为22.5ms,节点发送镜像页请求所需时间保持为15.5ms不变,来回确认帧时间为5.76ms。当镜像页大小为64字节时,传输所需时间为(22.5+15.5+5.76)*1765=77236ms,也与表3的测量值77.2基本相符。当镜像页大小为6400字节时候,即请求命令减少到原来的百分之一,时间缩短了50s,更新效率大幅度提高,基本达到了单个节点更新速度的极限。
5. 结论
介绍了一种基于ZigBee的空中下载技术,非常适用于短距离的无线传感网络应用场合。通过无线更新固件,免去了回收更新节点所需时间,可以达到更新完成后不破坏当前网络拓扑结构的效果。另外,在Z-Stack协议栈设计了一种镜像页请求更新方式,实验结果表明,当批量更新整个网络时,既可以提高节点的更新效率,又可以大大减少网络的更新流量,并节省节点的功耗;当进行点对点更新时,如果把响应间隔缩减为10ms,并把镜像页设置为足够大,单个节点的更新时间可以缩减为27.3s,接近单个节点更新速度的极限。至于使用批量的更新方式还是点对点的更新方式,视具体的应用场合而定。
全部0条评论
快来发表一下你的评论吧 !