陳 爽
(遼寧思凱科技股份有限公司,遼寧 丹東 118008)
隨著智慧城市概念的不斷深入,智慧生活理念不斷增強,互聯互通成為引領時代潮流的主題化代名詞,體現在燃氣行業的技術進步與發展的歷程為:普通機械式膜式燃氣表—預付費IC、CPU 卡智能膜式燃氣表—智能無線遠傳燃氣表—智能超聲波無線遠傳燃氣表。智能超聲波無線遠傳燃氣表規避了膜式燃氣表機械磨損的弊端,降低了燃氣集團供銷差,更有效地保障安全計量、安全用氣。但超聲波燃氣表[1]在應用過程中也存在諸如微小流量誤報、脈動流等問題,還可能存在其他潛在的、未知的風險。另外,隨著技術的進步,需要通過云端[2]獲取燃氣表上報的用氣情況進行用戶用氣習慣的大數據分析,以保障用戶加深用氣安全理念,同時掌握其他非硬件變動情況下用戶需求的改變。燃氣表的遠程升級變成了解決上述問題的一種必要的技術手段。
為解決超聲波燃氣表的代碼處理量過大、占用程序存儲空間過多,以及使用傳統的差分方式會導致極少的改動和產生較多的差分升級包等問題,選用或研發適宜的差分升級方式以及在不改變超聲波燃氣表本身功能的前提下降低代碼存儲空間顯得尤為重要。減少升級包,降低程序升級過程中的交互次數有如下優勢:首先,市面上的超聲波燃氣表大都采用松下的方案進行數據采集,正常模式下松下換能器2 s 發送一次數據到燃氣表主控板,故降低無線數據傳輸的交互次數可有效地緩解甚至避免計量數據被打斷或丟失的問題;其次,普通程序升級方式下,由于升級包數過多,長時間占用信道,影響其他表具的附網成功率;再次,普通程序升級方式下,升級時間較長,這對于電池電量的損耗是未知的,同時多包數據交互也大大降低了程序升級的一次成功率。因此,減少程序升級過程中的交互次數十分必要。
超聲波燃氣表通常具備如下功能:計量數據的采集、處理、存儲,拆表、倒流、反裝、脈動流及安全功能檢測,無線通信配合紅外通信的遠程控制等。其代碼空間的占用量大于等于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,后跳轉于引導程序中,將解碼包覆蓋原有應用程序,最終實現程序升級。
程序存儲空間分為4 個區域,分別為:搭載底層驅動的BootLoader 區、Patch 包存儲區、應用程序運行區、Patch 包解壓縮暫存及備份程序存儲區。搭載底層驅動的BootLoader區的作用是:將應用程序中固定不變的底層驅動子程序全部生成到引導程序中,以便程序復位時代碼從BootLoader 程序跳轉到應用程序后,應用程序能夠對引導程序中的底層驅動程序進行精準調用。Patch 包存儲區的作用是:將通過差分包生成組件生成的壓縮后的差分包,通過無線遠傳或紅外近端無線通信等方式發送到指定的超聲波燃氣表終端,經判定接收數據無誤后,存儲于該區域備用的數據存儲位置。應用程序運行區的作用是:作為存儲程序正常執行時的表端功能性程序的存儲位置。Patch 包解壓縮暫存區及備份程序存儲區的作用是:既可以將壓縮的Patch 包解壓縮后暫時存儲到該區域,然后整體搬運到Patch 包存放區,又可將解Patch后所還原出的待升級應用程序存放于此位置,以便待升級應用程序校驗成功后直接覆蓋原應用程序存儲區。程序存儲空間分區示意圖如圖1 所示。
將底層驅動程序固化到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 函數:

值得注意的是,此例中僅為如何在應用程序中調用引導程序的一個函數,如有多個驅動程序,依次排列即可。
由于底層驅動程序是無須進行更改的單片機硬件配置應用程序,諸如串口驅動程序、定時器驅動程序及液晶顯示驅動程序等,均為可被BootLoader、當前執行的應用程序、待升級的應用程序重復利用的代碼。該底層驅動程序固化的實現方式,避免了在BootLoader、當前執行的應用程序、待升級的應用程序中重復定義3 次,節省了2 倍的代碼空間,可將節省下來的代碼空間分配給Patch 包存儲區,這樣就避免了因程序存儲空間的不足而需引入外掛FLASH,從而造成成本增加等方面的困擾。
新型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 算法還原出第三個文件。
新型Patch 差分包的生成原理為:同時獲取當前應用程序文件中各函數首地址,及待升級程序文件中各函數首地址,并將地址順序由大到小排序。通過對比兩文件中均存在的各函數對應存放位置偏移情況,及函數占用空間長度的差異,精準定位差異區。對于刪減或者新增的代碼,須做額外標記,以便在應用程序中進行填充。最后利用Diff and Patch 開源代碼進行改造,從而生成新型Patch 差分包,該差分包的字節數必小于等于直接封裝好的利用Diff and Patch開源代碼所生成的字節數。
值得注意的是,對于使用類似Keil 開發工具開發的代碼可借助于.map 文件進行調用;否則,新型Patch 差分包的生成方案必須借助于嵌入式程序配套處理。需要在嵌入式程序中進行如下操作:首先,定義const unsigned int 類型的不定長數組,在數組中存放全部使用的main 函數及子函數的入口地址;然后,將print 打印函數映射到指定可輸出數據的串口;最后,將存放程序入口地址的數組中的成員依次進行打印輸出,全部傳遞給差分包生成組件。.map 文件導出程序地址的格式如圖2 所示。

圖2 .map 文件導出程序地址格式
差分包生成組件包括:升級包選擇區,用以導入原程序文件及待升級程序文件的可拖拽式接口;串口設置區,用以配置與表端相匹配的串口波特率、校驗位、停止位及數據位,實現與超聲波燃氣表主板進行串行數據通信;差分升級區,可配置壓縮率,可點擊“導入文件”按鈕,導入差分包到顯示窗口,可選擇進行本地升級或無線升級的功能。差分包生成組件的界面如圖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 升級流程。
AES 加密算法是一種使用密鑰加密的標準區塊加密算法,可彌補DES 算法的缺點,并且可以取代它。AES 加密算法是一種對稱加密算法,在國際上是通用的,其CBC 模式極大地增加了破解難度, 且FM33LG048 單片機中自帶硬件AES 加密機制,故選取該算法對超聲波燃氣表的差分包進行加密。AES 加密算法的CBC 模式的數據加密流程如圖4 所示。

圖4 CBC 模式的數據加密流程
SM2 算法是國家保密標準非對稱算法[8],該算法雖然不具備國際通用性,且私有性很強,但其運用的橢圓曲線公鑰密碼算法的安全性是超乎想象的,即便使用極短的密鑰也能提供相當大的安全性。故選用該算法作為超聲波燃氣表差分包加密后的驗簽算法的性價比是極高的。
隨著燃氣行業各項技術和通信技術的進步,燃氣行業不斷與時俱進、突破發展成為了必然趨勢。將無線通信技術的優勢發揮到極致,使廣大燃氣用戶收獲更多方便的體驗,也是新型超聲波燃氣表需要更新、迭代的根本原因。本文中所描述的基于FM33LG048 的超聲波燃氣表新型差分升級系統的設計理念正是服務于提升燃氣用戶使用體驗、提升燃氣行業技術水平這一思想。這一新型差分升級系統的設計,借助于LoRa[9]、4G、NB(采用SOTA 升級方式最佳)、5G 等無線通信方式[10]得以實現。該新型差分升級方案大大減少了差分升級的交互報文包數,降低了干擾計量精確度的風險,節省了表具升級時進行無線通信交互的功耗,減少了因占用信道時間過長而阻礙其他表具聯網進程的風險,提升了用戶使用超聲波燃氣表的體驗,為燃氣集團及燃氣用戶帶來極大的便利。