嵌入式多节点的无线批量程序更新系统设计(二)
缓冲区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平台上。
尚未实现程序的动态更新,即每次更新前都要将正在运行的程序关掉,强制节点进入准备状态。可以分配一个专用线程用于程序更新,同时为了避免更新对正在运行的程序造成影响,需要在更新过程中引入动态链接技术
评论