嵌入式多节点的无线批量程序更新系统设计(二)
扫描二维码
随时随地手机看文章
3.2 可靠数据分发协议的设计
在阐述具体的设计思路之前,先提出以下应用场景的假设。
假设一:网络节点不支持高级的操作系统。可以理解为必须考虑节点处理和通信能力有限,而且通信协议要从底层(如MAC层)实现。
假设二:大部分待烧录节点分布在数据基站的通讯范围之内。可以理解为通信协议不需要实现复杂的多跳通信和流水线,可以充分利用数据基站第一次数据广播,这一点下文会详细阐述。
基于以上两点假设,可靠性数据分发协议的具体设计如下。
考虑到不同平台的无线收发模块提供的服务接口和通信质量的差异以及程序更新对网络可靠性的要求,通信协议选择在网络层实现可靠数据分发的机制,协议只需要硬件平台在MAC层提供收发数据帧的应用接口即可。协议中,数据分发分为两个阶段:第一轮发送阶段和节点间交流阶段。图4.2为两个阶段通信方式示意图。
(实线代表发送完整数据文件,虚线表示发送数据页)
1、第一轮发送阶段。
数据基站(如PC)在接收节点准备好后不间断广播数据帧,直至数据发送结束;接收节点尽力接收数据,并记录自己已有数据帧的id信息,期间不向源节点发送反馈信息。
在原始的Deluge协议中没有这一阶段,因为Deluge协议中可能无线传感器网络庞大,分布范围也较广,所以数据分发一旦启动,所有接收到数据的节点都参与到数据发送中来;而本设计中,网络充分利用了假设二中的节点分布条件,通常情况下,在第一轮发送结束后,相当大比例的节点就已经接收到了大部分的数据,而这个过程中因为只有数据基站在发送广播,网络中数据传输的效率是最高的。当然,这种节点分布条件不满足的情况也不会明显降低数据分发效率。
节点间交流阶段。
交流阶段参考了trickle算法的“polite gossip”策略,所有节点(包括数据基站)都参与到交流中去。每个节点的交流的目的都是相同的,即将自己拥有的数据包发送给需要的节点和请求并接收自己需要的数据包。
第2阶段是保证可靠性的关键,协议中让源节点也参与到交流中来,这是为了防止网络状况极差以至在第一轮发送结束之后所有节点接收数据的总和都不构成完整数据文件的极端情况。这一步中,节点长时间处于“维护”状态标志数据分发结束。
节点首先广播广告,每一个广告包含一个摘要(φ),摘要(φ)由两部分组成:(1)本节点的IP标识v。(2)本节点的最大可用页号p,即φ(v,p)。可用页号p的定义:页p所包含的包被节点全部接收,称页p完成。页p被完成并且它之前的所有的页(0,p)也被节点全部接收,称页p可用。节点通过广告来了解对方拥有的数据信息,继而向比自己数据更完备的节点发送数据页请求。协议中将时间分成时间片(round),在每一个时间片中,节点来决定是否广播一个广告。假设时间片的长度由Tm,i来表示,它的上下界由Tl和Th来表示,则有取Tl
交流阶段中,节点拥有“维护”、“请求”和“发送”中的人一个状态。节点在“维护”状态广播广告并听取其他节点的广播;在请求阶段向其他节点发送数据页请求,并接收对方发来的数据;在发送状态广播被请求的数据页。图4.3为状态转换示意图。主要的交流规则如下。
(1)“维护”状态规则
M1: 假设时间片i的开始时间为ti,节点在ti+ri的时间段内,若接收不到广告φ'=φ,则广播广告φ;若收到与φ不一致的广告(包括φ'=φ、广告帧和数据帧等),则调整时间片为Tl,并立即重新开始时间片;若接收到广告φ'=φ,则调整时间片为min(2*Tm,i ,Th )。
M2: 节点在收到广告φ'(v',p')中p'大于自身的最大可用页p时,转向“请求”状态,向节点v'发送数据页请求;节点收到请求帧,则转向“发送”状态,广播被请求数据页。
规则1能控制冗余广告的发送,节约网络资源,并且根据网络状况动态调整时间片长度,从而是网络资源得到有效的利用。
规则2实现从“维护”状态到“请求”和“发送”状态的转换。
(2)“请求”状态规则:
M3:若节点在向源节点发出数据页请求后节点在时间t(t为自定义时间长度,是经验值,根据网络状况而定)内没有收到数据,则再次发送请求,若累计请求次数大于k(k为自定义次数),则认为请求失败,返回“维护”状态;若节点接收到数据页,则在接收结束后返回“维护”状态。
规则3中考虑到网络的质量因素,定义了等待时间t和最大请求次数k。
(3)“发送”状态规则:
M4:节点进入“发送”状态立即广播被请求的数据页,广播结束后返回“维护”状态。
规则4中要注意的是,节点以广播的方式发送数据,这意味着处于“请求”状态的节点可以接收任何节点(不一定是它请求的指定节点)发送的符合其需要的数据包,这也是协议中避免网络冗余的一个体现。
以上是本设计中可靠数据分发协议的全部内容,本文在下一节中将详细论述协议的软件设计实现。
3.3 可靠数据分发协议的软件设计实现
协议的软件设计在网络层实现,涉及到MAC层接口的调用。本节先简单介绍本设计实验平台上网络模块提供的MAC层应用接口,然后详细论述软件的设计和实现。
3.3.1 MAC层接口简介
首先做两点说明。
第一,设计中使用的MAC层接口不提供绝对可靠的网络通信。一方面是因为设计使用实验室自制的硬件平台主要用于做群体实验,而群体实验不需要可靠的网络通信,所以平台的通信模块也没有能实现可靠通信的机制;另一方面要求MAC层提供可靠通信也不是必要的。
第二,网络层只使用了MAC层提供的数据帧发送和数据帧接收两个接口,网络层的帧结构包含在MAC数据帧的数据域中。
从第一点可以看到,协议在网络层实现可靠数据传输的机制,降低了对MAC层通信质量的要求,而第二点说明协议仅仅需要MAC层提供两个最基本的应用接口。本设计中的可靠数据分发协议对底层通信的要求很低,具有较好的鲁棒性和可移植性。
本设计实验平台上提供的MAC层数据帧发送命令结构如图4.4所示,其中区域3为数据域,包含网络层的帧结构,另外节点在MAC层以广播的方式通信,所以命令中不包含源节点和目的节点的地址信息。MAC层接收到数据帧后,将数据域分离出来存储到接收缓存区;发送数据时,将发送缓存区中的数据加上MAC层数据帧的头部和尾部并发送出去,网络层只关心发送和接收缓冲区中的数据。这里规定以下章节中提到的各种帧结构均指网络层帧结构。
3.3.2 可靠数据分发协议的数据结构设计
网络层数据要经过缓存,解析再到存储或者执行三步操作,并且不同种类的帧要区别处理,因此一个好的数据结构设计方案对简化数据处理操作和提高数据处理效率是非常有必要的。图4.5为网络层数据流图,数据帧的流向为:
从MAC层读入后放入原始数据缓冲区;
经解析后得到帧结构;
将帧结构作相关处理后仅提取页号(p)、帧号(id)和数据(data)放到写flash缓冲区;
写flash。
注意以上是数据帧的流向,除数据帧以外的其他类型帧(如请求帧,结束帧等)只执行第(1)、(2)步操作。下面着重论述图中每个阶段涉及到的数据结构。[!--empirenews.page--]
缓冲区Deluge_buf
Deluge_buf是一个环形缓冲区,用于缓存原始的网络层数据。缓冲区实际上是由一个环形链表、两个指针和一个整数组成。链表的每个节点用于存储实际数据,节点数目根据需要而定;一个tail指针和一个head指针,分别指链表的读出点和写入点,执行一次读出或写入操作后,tail或head指针都向前移动一次,整数的作用是统计当前链表上可用节点的数目。Deluge_buf结构体定义如下:
struct Deluge_buf {
struct data_entry queue_data[QUEUE_LENGTH]; // The data of current queue
uint8 recv_num;
uint8 queue_head;
uint8 queue_tail;
};
值得注意的是结构体data_entry中Payload项的组成在不同类型的帧中是不同的,比如数据帧中Payload包括页号p、帧号id和数据data以及数据长度data_len,而广告帧中只包含p和id,因此解析方法要根据type值来区分。
帧结构DelugeData
如图五所示,DelugeData定义了帧类型(type)等六个数据项,设计中根据不同的帧类型规定了各个数据项的含义,具体定义如表4.1所示,“—”表示该数据项在帧中没有定义。
表4.1 DelugeData中数据项含义的定义
数据项 帧类型 |
type |
v |
p |
id |
data |
data_len |
数据帧 |
DATA |
版本号 |
页号 |
帧号 |
数据 |
数据长度 |
结束帧 |
END |
版本号 |
页号 |
帧号 |
— |
— |
广告帧 |
ADV |
版本号 |
页号 |
源节点标识 |
— |
— |
请求帧 |
REQ |
版本号 |
页号 |
目标节点标识 |
— |
— |
命令帧 |
CMD |
命令参数 |
— |
— |
— |
— |
3、缓冲区Flash_buf
因为写flash操作比网络传输慢得多,为了避免写flash拖慢整个数据分发速度,建立缓冲区Flash_buf用于缓存准备好的数据。Flash_buf也是一个环形缓冲区,原理和Deluge_buf相同。缓冲区的节点包含p、id、data三个数据项和指针域next,其中data是要写入flash的数据,p和id用于计算待写入的flash地址。
3.3.3 可靠数据分发协议的软件架构设计
可靠数据分发协议的软件构架设计包括发送端和接收端两块内容。发送端软件运行在数据基站上,分为两个阶段,第一阶段通知节点连续地发送整个文件,第二阶段运行状态机参与到节点的交流中去;接收端软件运行在待烧录节点上,第一个阶段尽可能多的接收基站发送来的数据,第二阶参与节点间讨论。因为发送端第一阶段软件比较简单,第二阶段和接收端相同,所以这里只重点介绍接收端的软件构架设计。
第一阶段:
程序完成初始化后进入准备接收状态,当数据帧到来时将数据提取出来写到flash相应的地址(地址由页号p和帧号id计算得到),并将该帧标记为“完成帧”;若接收到结束帧,则记录结束帧的页号pmax和帧号idmax并进入第二阶段;若接收到其他类型帧则直接进入第二阶段。第一阶段的软件流程图如图4.6所示。
第二阶段:
完成第一轮接收后,程序运行ADV-REQ-DATA状态机,和其他节点交流,完善或帮助其他节点完善数据文件。状态机分为MAINTAIN(维护)、RX(请求)和TX(发送)三个状态,程序首先进入MAINTAIN状态。MAINTAIN状态下,程序监听广告帧和请求帧并在适当时机发送广告,根据协议规定,程序可能跳转到RX状态或TX状态进行数据帧请求和发送操作,操作完成后返回MAINTAIN状态。程序中定义一个最长时间tmax,如果MAINTAIN状态持续时间超过tmax,则认为整个数据分发过程结束,程序检查自己接收到的数据是否完备后退出。第二阶段的软件流程图如图4.7所示。
四 系统测试
本测试将用三个程序作为用例,以测试系统的可用性。三个程序分别为:
Led.bin实现简单的跑马灯;
GoAhead.bin 三辆小车将一直向前方走,即使碰到障碍物也不停止;
RandomWalk.bin 三辆小车将进行随机行走,并且碰到障碍物后会进行壁障,转弯。
首先我们将批量更新跑马灯的程序,然后我们来看GoAhead.bin,如图5.1所示。完整的程序镜像大小为3340Bytes
当前在节点上已经运行了Led.bin,我们将使用Led.bin和GoAhead.bin进行比较,生成patch.bin文件,即补丁文件。
我们看到,生成的patch.bin文件仅仅是原程序GoAhead.bin的1/3大小!图5.3是patch.bin代表的命令(截取一部分)。
下面从GoAhead.bin 生成 RandomWalk.bin,RandomWalk.bin的大小如图5.4所示:
图5.5从生成的patch.bin文件的大小可以看到,其为RandomWalk的大约1/3。但有个值得注意的地方是,RandomWalk.bin比GoAhead.bin大了1000多个字节。添加的着1000多个字节是占patch.bin的主要内容。可见发送patch.bin比较适合于修改部分变量或者函数的时候。如果是单纯的增加功能,比较适合于发送完整的镜像文件。
五 总结
测试结果表明,本设计实现了可靠性无线批量嵌入式节点程序更新,烧录出错率低;更新效率高;不依赖操作系统,具有很好的可移植性,项目总体上实现了设计的目标。另一方面由于时间限制,系统仍然存在一些不足。以下是设计中几点需要优化的地方和相应的改进意见。
系统在Linux环境下进行了开发和应用,没有开发Windows版本。项目组准备在下一阶段把系统移植到Windows平台上。
尚未实现程序的动态更新,即每次更新前都要将正在运行的程序关掉,强制节点进入准备状态。可以分配一个专用线程用于程序更新,同时为了避免更新对正在运行的程序造成影响,需要在更新过程中引入动态链接技术