当越来越多的物联网水表加入抄表系统后,实现了水表数据的信息化,并且当水表终端需要技术更新时,通过网络方式来升级产品可以高效修复设备面临的问题,减少用户损失,降低维护成本,但同时也对有限的网络资源形成负担。
当前终端的无线远程升级技术多采用单一的整包升级策略,存储空间占用率高,网络资源占用量大,升级成功率不高。
针对上述问题,引入了应用于Android端的开源差分算法HdiffPatch,介绍了差分升级在物联网抄表系统中的实现架构和方法,并通过重编译实现算法在Windows服务器端及嵌入式水表终端的应用。
物联网水表指的是在计量基表的基础上,加入无线远传模块(GPRS、NB-IoT等),组成的新型智能水表,它实现了集流量计量、流量采集、数据存储及无线传输于一体的强大功能。
当越来越多的物联网水表加入抄表系统后,对用水片区的水量管理及数据分析提供了可靠的依据,为用户用水行为管控提供了及时有效的操作机制,也为水表设备运行的远程监测提供了方便的平台,但同时也对抄表系统的网络带宽提出了一定的要求。
当设备投入市场之后,由于相关技术的迭代,设备运行可能会暴露其软件代码中的某些致命弊端;由于客户需求更新,设备软件需要升级以增加或者修改原来的功能。
当物联网设备投入市场后,厂家开发安全有效的空中升级方案,只需要在网络平台上把升级软件通过无线方式下发给设备,实现设备中的可执行代码更新。
无线升级面临着几个考验:
目前国内外固件设备的无线升级方案按照实现策略可分为整包升级和差分升级。
整包升级需要将新版本的完整软件包进行打包,设备接收完所有升级包,经过校验算法验证包的有效性和完整性后,替换旧版本的应用代码。
整包升级的方式接近于整个固件的镜像,操作简单,易于实现,对网络平台及设备端的设计实现要求不高。
差分升级又叫增量升级,是将固件的新旧版本的程序数据文件做差异,形成升级需要增量包,而对于两个版本中相同部分则不需要做升级处理,以此通过传输更少的数据实现同样的升级效果。
在实现架构上,差分升级系统需要在升级服务器侧和终端设备上分别部署差分算法,服务器比较新版本文件对旧版本文件所作的修改,并通过差分算法对这些数据以特定的格式打包、优化压缩,形成差分文件(patch文件);然后通过指定的协议,设备端接收完该差分文件,校验完成后,利用差分算法还原差分文件,并通过组合旧版本程序文件,得到目标数据文件,实现升级。
显然,经过服务器侧后生成的patch文件,远远小于新版本程序文件,而对于固件资源受限的设备终端来说,如何寻找一种高效的差分算法,实现以最小数据量来描述差分信息,并且以有效稳定的方法进行信息传递和文件还原,是差分升级的重要研究内容。
在构造差分增量包中,常见的算法有Bsdiff算法、Xdelta算法、Hdiffpatch算法等。
在匹配新旧文件过程中,有部分源代码内容完全相同,有部分源代码相似度很高,只有部分字节作了稀疏改动,另有一些源代码内容相同,但是存储地址存在一个固定的偏移量,对于这一特性的源代码数据,具有高度的可压缩性。Bsdiff算法引入了diff string的概念,在新旧文件中找到这样的两部分内容,求出字节的差异,作为diff string进行压缩。而对于不符合要求的新文件源码中新增部分,作为extra string进行保存。
Bsdiff算法在匹配时,先对旧文件的所有字符进行后缀排序形成一个字典,然后使用二分查找算法找到最优的匹配长度,依次得到整个文档所有的diff string和extra string,把这些文件信息以bzib2的方式压缩成升级增量文件。
Bsdiff算法的增量文件中的数据由四部分组成:Header,ctrl block,diff block,extra block。
设备端在接收到patch文件后,解压文件,并根据差分文件的组成格式,通过bspatch算法,还原生成新文件。
由Bsdiff算法原理可知,它所生成的patch文件并不会比源文件小,但是文件结构压缩性强,导致传输的升级数据量比完整升级要小很多,有效减少了冗余数据传输量。Bsdiff 算法高度依赖压缩算法,当升级文件修改的内容小概率地满足稀疏变化时,差分文件的压缩效率降低,相比整包升级的优势不明显。
Xdelta 和其他的差分升级算法一样,也需要对新文件和旧文件进行比较匹配作差分。在产生 patch 包时,Xdelta 可采用 hash 或者 suffix trees 等算法来寻找最大的匹配长度的字符串。
Xdelta 差分算法的 patch文件中用到了 add、run 及 copy 三种命令。其中 add 用于将匹配到的指定长度的字符串从源文件拷到目标文
件,run 用于在目标文件中加入新文件的增加部分,copy 将匹配到的文件成块的移动到目标文件中的目标地址上。
Xdelta 对增量文件采用 Vcdiff 格式的编码方式,用 128 进制的数据表示形式,经过重编码的字符,相较于原数据节省了存储空间,达到了高效压缩的目的[9]。
Xdelta 算法的 patch 生成过程可通过其他算法来优化,考虑到设备端的内存消耗,patch 过程引入了Windows 块技术,随着 Windows 块变大,可达到的最长字符串的匹配结果越精确,产生的 patch 文件越小,但同时也会消耗更多的内存资源。因此,采用高效的匹配优化算法和适合的 Windows 块大小,是 Xdelta 算法的关键。
Hdiffpatch是一种高效的增量算法,在运行时间复杂度及内存空间占用率上相较于前两种算法存在很大的优势。
Hdiffpatch在差异文件生成阶段引入了覆盖线C的概念,用于标志新旧版本文件的匹配度。
算法将两版本程序文件看成两个具有不同长度的数组,分别表示newData[m]和oldData[n]。
覆盖线C是点Ei.jj的集合,其中newData[i] = oldDta[j]。
如果C = {Ei,j,Ei+1,j+1,…,eI+K,J+K},表示该覆盖线的长度为k。
由此可知,经过匹配之后存在许多长度不等的覆盖线,根据差分包制作经验,当覆盖线长度大于7时,增量算法优势明显。
patch文件就是所有满足要求的覆盖线和newData[m]中没有被匹配上的数据组成的文档。
其中覆盖线表示信息结构包括:newPos,表示在新文档中的起始位置i;oldPos,表示在旧文件中的起始位置j;length,表示覆盖线长度k。
Hdiffpatch算法对匹配的覆盖线采取优化措施。其中包括:
Hdiffpatch算法产生了较小的升级包,当水表终端接收到升级包并且还原成最新文件后,需要对控制CPU中的执行代码进行更新升级。
本方案中采用的智能水表终端使用 STM32L071,其具有 192KB 的 FLASH,6KB 的片内 EEPROM,20KB的 RAM,能够实现多种低功耗运行模式,完全满足智能水表终端在实现流量数据计量、存储及与无线服务器通信功能的基础上,加入差分升级的功能。
而在加入差分升级之后,bootloader 中还将包含 Hdiffpatch 算法及与服务器进行patch 差分包传输通信所有流程。
由于在 Hdiffpatch 算法中需要在旧文件的基础上作新程序文件还原,因此会存在两个版本的文件同时存在于 FLASH 的情况,这对于升级失败时,设备还能继续正常运行起到保障作用。对于 CPU 的存储区,水表终端作了如下划分[14]:
终端升级流程实现
终端升级实现是差分升级系统中的关键部分,它负责增量升级文件的接收、差分算法的还原及固件的更新。
基于终端控制器CPU的RAM区容量的限制,水表设备不能一次性接收升级文件,而是采用分帧多包的模式。
当所有帧都接收完全后,CPU按照Hdiffpatch算法的patch文件格式解析文档,进行算法还原。
物联网智能水表使用一次性锂电池供电,保证安装及使用的便捷可靠。
在应用程序中,终端控制器合理使用 NB-IoT 的工作模式,并根据使用场景对表计量的频度和方法进行控制,既满足了客户的使用要求,又相对延长了产品电池使用寿命。
空中升级的使用频率相对较低,但是它一次使用的耗电量在所有应用功能中是最大的。
因此,如何采用合理的手段规避不必要的电耗也是空中升级系统要考虑的一个问题。
本方案采用Hdiffpatch算法来产生差分升级文件patch,在很大程度上缩小了空中升级的数据传输量,拉低了升级操作的总耗电量,成为降低升级功耗的关键技术。
升级一开始,服务器查询设备端当前软件版本号,如果与要下发的版本号一致,则认为没有升级的必要,退出升级操作。
这种架构,仅用一个交互信息就实现了升级流程走向,避免了不必要的传输步骤。
当空中传输过程出现网络故障时,终端收不到正确的服务器数据后,在连续申请三次升级包后,设备为了节省电耗,进入休眠模式。
待下一周期,网络恢复后,设备不需要重复传输已经接收完的数据包,而是进入断点续传,减少了冗余的操作,简化了升级步骤