NB 超声波燃气表的新型差分升级系统实现
2023-10-24陈爽
陈 爽
(辽宁思凯科技股份有限公司,辽宁 丹东 118008)
0 引 言
随着智慧城市概念的不断深入,智慧生活理念不断增强,互联互通成为引领时代潮流的主题化代名词,体现在燃气行业的技术进步与发展的历程为:普通机械式膜式燃气表—预付费IC、CPU 卡智能膜式燃气表—智能无线远传燃气表—智能超声波无线远传燃气表。智能超声波无线远传燃气表规避了膜式燃气表机械磨损的弊端,降低了燃气集团供销差,更有效地保障安全计量、安全用气。但超声波燃气表[1]在应用过程中也存在诸如微小流量误报、脉动流等问题,还可能存在其他潜在的、未知的风险。另外,随着技术的进步,需要通过云端[2]获取燃气表上报的用气情况进行用户用气习惯的大数据分析,以保障用户加深用气安全理念,同时掌握其他非硬件变动情况下用户需求的改变。燃气表的远程升级变成了解决上述问题的一种必要的技术手段。
为解决超声波燃气表的代码处理量过大、占用程序存储空间过多,以及使用传统的差分方式会导致极少的改动和产生较多的差分升级包等问题,选用或研发适宜的差分升级方式以及在不改变超声波燃气表本身功能的前提下降低代码存储空间显得尤为重要。减少升级包,降低程序升级过程中的交互次数有如下优势:首先,市面上的超声波燃气表大都采用松下的方案进行数据采集,正常模式下松下换能器2 s 发送一次数据到燃气表主控板,故降低无线数据传输的交互次数可有效地缓解甚至避免计量数据被打断或丢失的问题;其次,普通程序升级方式下,由于升级包数过多,长时间占用信道,影响其他表具的附网成功率;再次,普通程序升级方式下,升级时间较长,这对于电池电量的损耗是未知的,同时多包数据交互也大大降低了程序升级的一次成功率。因此,减少程序升级过程中的交互次数十分必要。
1 差分升级方案的制定
超声波燃气表通常具备如下功能:计量数据的采集、处理、存储,拆表、倒流、反装、脉动流及安全功能检测,无线通信配合红外通信的远程控制等。其代码空间的占用量大于等于60 KB,远大于无线远传膜式燃气表所使用的代码空间。
考虑到针对指定硬件主板,其AD 采集、I2C、SPI、液晶驱动等底层驱动程序是固定不变的,故采用一种新思想:将固定不变的底层程序固化于BootLoader 程序中,应用程序可通过指针方式,调用引导程序中的底层驱动程序,从而通过降低应用程序的代码空间,节省单片机硬件资源(程序存储空间)的同时,间接降低差分程序的差分包数。在此前提下,可选取性价比较高且资源满足当前需求的国产单片机:FM33LG048。
采用新型的差分升级包的生成方式:借鉴效率较高且便于应用的Diff and Patch 差分包生成方式,结合单片机输出全部子函数入口地址,以供上位机精准比对当前APP 程序与待升级APP 程序的差异的方式,进行差分包[3]的生成。在此基础上,为满足对差分包的进一步压缩,选用可调整压缩等级的LZO、LZW、GZIP 等方法对差分包进行数据压缩。
保障数据安全、数据传输的完整性及防止外部数据攻击,也是值得考虑的技术亮点。综合考虑代码空间及数据加密的安全级别等问题,选用FM33LG048 自带的AES128 硬件加密模块(加密模式选用CBC 模式[4],该模式加密安全系数较高,不易被主动攻击)。配合使用场内自定义的SM2[5](椭圆曲线公钥密码算法)作为数字签名方法,以保证数据完整性。
基于上述应用情况,本文重点介绍了一种新型差分升级方式。该方法需将应用程序中驱动层程序固化于引导程序中,选用Diff and Patch 的文件差分方法对文件进行差分,并配合可配置压缩率的数据压缩方法,通过无线数据传输的方式将加密后的Patch 包传递到燃气表内,在应用程序中进行解压缩、解Patch,后跳转于引导程序中,将解码包覆盖原有应用程序,最终实现程序升级。
2 程序空间分区及BootLoader 中底层驱动程序固化的实现
2.1 程序存储空间分区
程序存储空间分为4 个区域,分别为:搭载底层驱动的BootLoader 区、Patch 包存储区、应用程序运行区、Patch 包解压缩暂存及备份程序存储区。搭载底层驱动的BootLoader区的作用是:将应用程序中固定不变的底层驱动子程序全部生成到引导程序中,以便程序复位时代码从BootLoader 程序跳转到应用程序后,应用程序能够对引导程序中的底层驱动程序进行精准调用。Patch 包存储区的作用是:将通过差分包生成组件生成的压缩后的差分包,通过无线远传或红外近端无线通信等方式发送到指定的超声波燃气表终端,经判定接收数据无误后,存储于该区域备用的数据存储位置。应用程序运行区的作用是:作为存储程序正常执行时的表端功能性程序的存储位置。Patch 包解压缩暂存区及备份程序存储区的作用是:既可以将压缩的Patch 包解压缩后暂时存储到该区域,然后整体搬运到Patch 包存放区,又可将解Patch后所还原出的待升级应用程序存放于此位置,以便待升级应用程序校验成功后直接覆盖原应用程序存储区。程序存储空间分区示意图如图1 所示。
2.2 BootLoader 中进行底层驱动程序固化的实现
将底层驱动程序固化到BootLoader中的操作方式主要是采用了几个关键的C 语言语法,以及在Keil 中实现将变量或常量存于FLASH 的指定位置。具体实现方式如下:
(1)将自定义的底层驱动程序的子函数库文件夹添加到BootLoader 程序所在的工程下,这时如果该底层驱动程序不被BootLoader 程序调用,在该工程中是不会被编译的。故我们可新建一个const unsigned int 类型的不定长数组,将每一个底层驱动子函数的地址取出存放于指定位置。例如:
const uint32_t func_table[]__attribute__((section(“.ARM.__at_0x00001000”))) ={(uint32_t)&API_ADC};
该语法的意义是,将API_ADC 子函数的地址取出,存放于0x00001000 地址所指向的FLASH 空间。
(2)要实现在应用程序中调用固化于BootLoader 的底层驱动程序,需在引导程序中开辟的存放驱动程序的首地址位置进行调用。接上例,已知底层驱动程序的全部子程序执行位置首地址均依次存放于以0x00001000 为首地址的数组func_table[]中,进行如下操作即可调用API_ADC 函数:
值得注意的是,此例中仅为如何在应用程序中调用引导程序的一个函数,如有多个驱动程序,依次排列即可。
2.3 BootLoader 中进行底层驱动程序固化的优势
由于底层驱动程序是无须进行更改的单片机硬件配置应用程序,诸如串口驱动程序、定时器驱动程序及液晶显示驱动程序等,均为可被BootLoader、当前执行的应用程序、待升级的应用程序重复利用的代码。该底层驱动程序固化的实现方式,避免了在BootLoader、当前执行的应用程序、待升级的应用程序中重复定义3 次,节省了2 倍的代码空间,可将节省下来的代码空间分配给Patch 包存储区,这样就避免了因程序存储空间的不足而需引入外挂FLASH,从而造成成本增加等方面的困扰。
3 可变压缩率新型Patch 差分包生成方式
3.1 Diff and Patch 思想的原理
新型Patch 差分包生成方式参考了Diff and Patch 思想,Diff 和Patch 是一对相互配合使用的算法工具。从数学的角度来说,Diff 算法是对两个有交集的集合的差运算,而Patch算法则是对两个有交集的集合的和运算(值得注意的是,对两个无交集的集合进行运算毫无意义)。Diff 的作用是比较两个相关联的文件的差异,并将差异记录下来,生成一个差分文件,即Patch 文件(又可称为补丁文件)。举例说明:现有文件A 和文件B,经过Diff 算法运算后生成文件C,该过程相当于A-B=C,而Patch 运算的过程为B+C=A 或A-C=B。故可知,对于A、B、C 文件,已知其中两个就能用Diff and Patch 算法还原出第三个文件。
3.2 新型Patch 差分包的生成原理
新型Patch 差分包的生成原理为:同时获取当前应用程序文件中各函数首地址,及待升级程序文件中各函数首地址,并将地址顺序由大到小排序。通过对比两文件中均存在的各函数对应存放位置偏移情况,及函数占用空间长度的差异,精准定位差异区。对于删减或者新增的代码,须做额外标记,以便在应用程序中进行填充。最后利用Diff and Patch 开源代码进行改造,从而生成新型Patch 差分包,该差分包的字节数必小于等于直接封装好的利用Diff and Patch开源代码所生成的字节数。
值得注意的是,对于使用类似Keil 开发工具开发的代码可借助于.map 文件进行调用;否则,新型Patch 差分包的生成方案必须借助于嵌入式程序配套处理。需要在嵌入式程序中进行如下操作:首先,定义const unsigned int 类型的不定长数组,在数组中存放全部使用的main 函数及子函数的入口地址;然后,将print 打印函数映射到指定可输出数据的串口;最后,将存放程序入口地址的数组中的成员依次进行打印输出,全部传递给差分包生成组件。.map 文件导出程序地址的格式如图2 所示。
图2 .map 文件导出程序地址格式
3.3 差分包生成组件生成差分包的配置流程
差分包生成组件包括:升级包选择区,用以导入原程序文件及待升级程序文件的可拖拽式接口;串口设置区,用以配置与表端相匹配的串口波特率、校验位、停止位及数据位,实现与超声波燃气表主板进行串行数据通信;差分升级区,可配置压缩率,可点击“导入文件”按钮,导入差分包到显示窗口,可选择进行本地升级或无线升级的功能。差分包生成组件的界面如图3 所示。
图3 差分包生成组件界面
差分包生成组件配置流程为:第一步,将原程序文件拖入旧文件存放区,将待升级程序文件拖入新文件存放区备用;第二步,配置串口参数(须根据超声波燃气表端的串口参数进行相应的配置);第三步,超声波燃气表根据与差分包生成组件间的私有协议,发送原程序文件及待升级程序文件的全部main 函数及子函数的入口地址(若存在.map 文件,则点击“解析.map”,利用该文件生成差分包);第四步,选择压缩率(本组件采用LZO 数据压缩方式);第五步,点击“导入文件”按钮,生成差分包。由图3 可知,导入的OLD2.bin、NEW2.bin 文件大小分别为75 264 B、75 260 B,生成的差分文件大小为5 547 B。由此可知用于程序升级的数据量大大减少了。
差分包生成组件支持本地差分升级功能(差分包已经按照私有协议进行分段,可直接用于对超声波燃气表的串口差分升级)。选用NB 模组作为超声波燃气表的无线通信模组[6]时,无线差分升级须基于SOTA升级技术[7],将组件生成的.bin格式的差分包文件导入AEP 平台的SOTA 升级组件中,并下发升级任务。等待表具主动上报后,执行SOTA 升级流程。
4 差分数据包的加密、验签模式的选取及应用
4.1 AES 加密算法的特点
AES 加密算法是一种使用密钥加密的标准区块加密算法,可弥补DES 算法的缺点,并且可以取代它。AES 加密算法是一种对称加密算法,在国际上是通用的,其CBC 模式极大地增加了破解难度, 且FM33LG048 单片机中自带硬件AES 加密机制,故选取该算法对超声波燃气表的差分包进行加密。AES 加密算法的CBC 模式的数据加密流程如图4 所示。
图4 CBC 模式的数据加密流程
4.2 SM2 验签算法的特点
SM2 算法是国家保密标准非对称算法[8],该算法虽然不具备国际通用性,且私有性很强,但其运用的椭圆曲线公钥密码算法的安全性是超乎想象的,即便使用极短的密钥也能提供相当大的安全性。故选用该算法作为超声波燃气表差分包加密后的验签算法的性价比是极高的。
5 结 语
随着燃气行业各项技术和通信技术的进步,燃气行业不断与时俱进、突破发展成为了必然趋势。将无线通信技术的优势发挥到极致,使广大燃气用户收获更多方便的体验,也是新型超声波燃气表需要更新、迭代的根本原因。本文中所描述的基于FM33LG048 的超声波燃气表新型差分升级系统的设计理念正是服务于提升燃气用户使用体验、提升燃气行业技术水平这一思想。这一新型差分升级系统的设计,借助于LoRa[9]、4G、NB(采用SOTA 升级方式最佳)、5G 等无线通信方式[10]得以实现。该新型差分升级方案大大减少了差分升级的交互报文包数,降低了干扰计量精确度的风险,节省了表具升级时进行无线通信交互的功耗,减少了因占用信道时间过长而阻碍其他表具联网进程的风险,提升了用户使用超声波燃气表的体验,为燃气集团及燃气用户带来极大的便利。