汪志瑩,李軍偉*,李興坤,李連強,許金鵬,劉寶巖
1.山東理工大學 交通與車輛工程學院,山東 淄博 255049;2.北京裕峻汽車技術研究院,北京 100016; 3.一汽解放青島汽車有限公司, 山東 青島 266217
隨著移動通信技術的飛速發展和汽車新四化(電動化、網聯化、智能化、共享化)建設的快速推進,車載控制器的功能越來越復雜,軟件更新越來越頻繁??罩邢螺d技術(over the air technology,OTA)有效降低了控制器軟件升級成本,為用戶提供了更多的訂閱服務[1-2],實現了車輛駕駛輔助系統、空氣懸架系統、車輛導航系統、影音娛樂系統、自動泊車功能等系統的更新[3],已成為未來汽車智能化發展的主要趨勢,相比手機等智能設備,車載OTA的應用環境更為復雜[4]。
為了提高混動商用車巡航控制器軟件升級效率,減少現場升級次數及人工調試成本,本文中從實際工程出發,設計了一套基于用戶數據報協議(user datagram protocol,UDP)的混動商用車巡航控制器的OTA升級系統,通過移動網絡實現軟件升級服務,同時為開發人員提供遠程調試功能,并通過混動商用車巡航控制器測試驗證。
混動商用車巡航控制器OTA系統基于Linux系統開發,分為服務器端和控制器端。為滿足數據傳輸的安全性,服務器端和控制器端之間必須有完整的檢查機制和不同的加密機制[5]。服務器端安裝在云服務器上,用于存儲控制器升級所需的軟件包,并完成升級任務的分發;控制器端安裝在混動商用車巡航控制器上,主要完成升級軟件包的接收和安裝功能。
設計OTA升級系統,使控制器端通過傳輸控制協議(transmission control protocol,TCP)/網際協議(internet protocol,IP)將要發送的信息打包后,通過4G通信模塊發送到附近的移動基站,再通過互聯網發送到云服務;服務器端解析接收到的報文,并通過互聯網將解析結果發送到控制器端,完成與控制器端的通信,實現軟件升級[6-7]?;靹由逃密囇埠娇刂破髅看纹饎訒r,自動運行OTA系統,確認服務器是否有更新任務。
1)發布升級任務。開發人員將升級軟件包上傳至服務器端,并在服務器端界面為控制器端指定升級軟件包,并選擇是否進入命令行調試模塊。
2)數字證書交換與驗證。由握手模塊完成服務器端和控制器端的數字證書交換和驗證,實現對稱加密密鑰的安全傳輸,并獲取控制器端的報文標識符(identification,ID)和軟硬件版本號。
3)命令行調試??刂破髦屑尤朊钚姓{試模塊,可滿足開發人員的遠程調試需要,實現調試命令請求,并向服務器端返回調試命令執行結果。
4)軟件包下載。由文件下載模塊確認控制器端的軟件升級版本,實現升級軟件包下載,支持文件下載斷點續傳,下載完成后驗證軟件包完整性。
5)文件備份與軟件升級。在控制器軟件升級前,由備份升級模塊檢測并判斷當前車輛狀態是否滿足升級條件,并進行文件備份;若升級失敗,則回滾重刷重新升級[8],確?;靹由逃密囇埠娇刂破鬈浖晒ι?。
基于系統總體方案和功能,設計通信模塊、握手模塊、命令行調試模塊、文件下載模塊和備份升級模塊,并完成服務器端界面的設計。
通信模塊是實現混動商用車巡航控制器OTA系統升級的基礎,主要功能包括基于UDP實現控制器端與服務器端的通信、通過循環冗余校驗碼(cyclic redundancy check,CRC)校驗報文準確性和通過加解密程序保證通信安全性,其中,控制器端與服務器端的通信是設計的重點。
2.1.1 UDP通信
由于服務器端需通過互聯網同時與多個控制器端進行通信,因此選取Linux提供的套接字接口作為通信端點,開發套接字初始化函數,設置套接字句柄,完成套接字初始化。選擇套接字協議簇為IPv4,類型為數據報套接字,即使用UDP實現套接字傳輸[9-10],進行網絡通信,該通信方式不需要維護連接狀態且適合一對多的通信。
在控制器端建立通信目標地址結構體,并在結構體輸入服務器端的IP地址和端口號[11],完成地址結構體初始化。由于網絡延遲時間為1 ms~1 s,為避免網絡波動造成通信失敗,設置套接字超時時間為2 s。套接字和地址結構體初始化完成后,進入發送和接收報文狀態。
2.1.2 CRC校驗
網絡傳輸過程中會隨機出現位翻轉、截斷、位缺失等錯誤,造成控制器軟件升級失敗,甚至功能失效,需采用報文校驗函數檢測。由于設計的升級系統中最長報文為1 410字節,因此選擇32位CRC進行報文校驗。
發送方根據代數編碼理論將校驗數據編碼為原始信息碼多項式D(x),最高次冪為校驗數據字節數m減1,生成最高冪次為m的固定多項式P(x);D(x)乘以2m(即左移m位),再除以P(x),所得的商式為Q(x),余式為CRC碼多項式C1(x),將C1(x)附在D(x)之后,即為信息碼多項式M(x),即M(x)=2mD(x)+C1(x)=Q(x)P(x),其中M(x)能被C1(x)整除[12]。
接收方將信息碼多項式M(x)除以P(x),若余數為0,則該報文數據通過CRC校驗,表明報文傳輸未發生錯誤;若余數不為0,則該報文數據未能通過CRC校驗,表明報文傳輸發生錯誤,需重新傳輸。為了簡化程序,本文中設計的升級系統中接收方計算接收報文數據的CRC校驗碼C2(x),通過對比C1(x)與C2(x)進行校驗。若二者相同,則該報文數據通過CRC校驗,表明報文傳輸未發生錯誤;若二者不同,則該報文數據未能通過CRC校驗,表明報文傳輸發生錯誤。
2.1.3 加、解密程序
為保證OTA通信報文在互聯網上傳播過程中的安全性和保密性,調用開放式安全套接層協議(open secure sockets layer,OpenSSL)庫,設計加、解密程序使通信模塊在網絡傳輸前加密報文,接收后解密報文。
設計加、解密程序時,首先定義加密標志flag的取值,根據flag的值選擇對應的加密和解密方式,調用不同的函數和密鑰,結合不同的加密算法,完成數據的加密或解密,并返回數據長度。若flag為-1,不對報文內容進行加密。若flag為0,使用非對稱加密算法,非對稱加密時,加密程序調用Linux內置的OpenSSL庫內RSA_public_encrypt()函數,使用接收方的非對稱加密密鑰Public_Key以117字節為數據單位加密數據;非對稱解密時,解密程序調用OpenSSL內的RSA_private_decrypt()函數,使用解密程序的私鑰Private_Key以128字節為數據單位依次解密數據。若flag為1,使用對稱加密算法,加密或解密時,均調用OpenSSL內的AES_ecb_encrypt()函數,使用對稱加密密鑰AES_Key對數據進行加密或解密,加密時設置模式為AES_ENCRYPT,解密時設置模式為AES_DECRYPT。通常,flag先置0,再置1,這是由于對稱加密的密鑰相同,只有非對稱加密之后,才能傳輸對稱加密的密鑰。
2.1.4 發送接收程序
UDP報文發送與接收過程流程圖如圖1所示。

a)發送過程 b)接收過程
由圖1a)可知:設計UDP報文發送程序時,將C1(x)附在D(x)后作為完整報文,調用加密程序加密后,執行Linux系統內的sys/socket庫中的sendto()函數將加密報文寫入4G通信模塊緩沖區,緩沖區按報文寫入順序向移動基站發送報文[13],若2 s未發送成功,則重新調用sendto()函數,若超時2次退出程序。
由圖1b)可知:設計UDP報文接收程序時,調用sys/socket庫中的recvfrom()函數取出4G通信模塊緩沖區的報文,若2 s內未取出報文,則重新調用recvfrom()函數,超時2次退出程序;調用解密程序解密取出的報文內容后,比較C2(x)與C1(x),若校驗碼相同,則校驗通過,若不同,則廢棄報文;報文校驗通過后,接收函數識別ID,調用相應的程序,進行數據處理。
2.1.5 通信協議
由于UDP中報文頭不能確認該幀報文的功能,為區分不同報文的功能,本文中設計OTA系統時,在報文頭部添加報文ID,用來標識報文的功能,報文ID對應的功能如表1所示。

表1 報文ID及對應的功能
握手模塊包括控制器端、服務器端2個模塊,握手模塊流程設計如圖2所示。

a)控制器端 b)服務器端
由圖2可知:控制器端將ID為0x12的報文(內含控制器數字證書),發送給服務器端,服務器端接收到控制器數字證書并驗證通過后,發送ID為0x11的報文;控制器端接收后,調用OpenSSL庫,驗證報文內服務器數字證書的有效期和數字簽名;若控制器未接收到ID為0x11的報文,或報文驗證未通過,則退出OTA系統;驗證通過后,設置flag=0,解析Public_Key,通過ID為0x10的報文(內含加密信息)發送控制器;若控制器接收到ID為0x10的報文,設置flag=1,解析AES_Key,同時將ID為0x50的報文(內含控制器端ID、軟硬件版本號等信息),對稱加密后發送至服務器端;若控制器未接收到ID為0x10的報文,則退出OTA系統;服務器端接收ID為0x50的報文,解密并核對,根據通信之前服務器端的設置,決定進入命令行調試模塊或者文件下載模塊。若服務器端接收到ID為0x28的報文,進入命令行調試模塊;若接收到ID為0x34的報文,進入文件下載模塊;若未收到ID為0x50的報文,結束程序。
命令行調試模塊無法直接執行命令,需要先新建一個文件流指針stream,用于存儲標準輸出流,再調用C標準庫中的popen()函數,新建一個管道,用于執行調試命令。由于popen()函數默認返回標準輸出流,為了避免錯誤輸出流,重新定向到標準輸出流,將popen()函數執行結果讀入字符串buf,再關閉文件流指針stream。命令行調試模塊包括控制器端、服務器端2個模塊,命令行調試模塊流程設計如圖3所示。

a)控制器端 b)服務器端
由圖3可知:控制器端發送ID為0x68的報文,向服務器端請求調試命令,服務器端先確認是否為調試請求,收到請求后若有調試命令,則向控制器端發送ID為0x28的報文(內含調試命令);若未收到調試請求或無調試命令,則等待重新接收報文;控制器端解析報文內容,區分命令類型,若是調試命令,則執行該命令,并將執行后的標準輸出打包成ID為0x68的報文,發送到服務器端;若是空命令,則繼續向服務器端請求調試命令;服務器端若收到調試結果,則顯示結果,否則檢測是否退出調試;若不退出調試,則等待接收調試請求;若退出調試,則結束調試程序;控制器重復上述過程,直至接收到服務器發出的ID為0x34的報文,退出命令行調試模塊,進入文件下載模塊。
設計文件下載模塊時,先新建數據緩沖數組rdata[20],檢測是否需要斷點續傳,控制器端獲取報文發送順序和進度,并將數據有序儲存到rdata[20],直至rdata[20]被寫滿、剩余報文不足20幀或出現超時錯誤時,檢測rdata[20]是否存在數據缺失。若沒有數據缺失,將rdata[20]寫入臨時文件,重新計算下載文件大小Size,并將其用ID為0x78的報文發送到服務器端;若數據缺失,則舍棄該組報文,不重新計算Size;重復接收報文程序,直至下載進度為100%后,關閉臨時文件。
文件下載模塊包括控制器端、服務器端2個模塊,文件下載模塊流程設計如圖4所示。
由圖4可知:控制器端接收到ID為0x34的報文并解析,獲取最新軟件版本號和該軟件包大小后,顯示升級信息,詢問用戶是否升級,并監聽用戶的標準輸入流,如果用戶輸入Y或者y則視為同意;服務器端接收到ID為0x74的報文,且同意升級,進入下載程序,否則結束下載程序;控制器判斷是否需要斷點續傳,如需要則先調整下載進度,否則直接下載軟件,文件下載完成后,服務器端發送ID為0x39的報文,傳輸軟件包哈希值,并調用OpenSSL庫計算軟件包哈希值,2個哈希值若相同,則驗證通過,否則服務器發送ID為0x74的報文,重新下載。

a)控制器端 b)服務器端
若文件下載中斷時,先排除中斷原因,再檢索下載目錄是否有與最新軟件版本號同名的臨時文件;若沒有,新建該臨時文件并設置Size為0,重新下載;若存在臨時文件,則需要進入斷點續傳,并設置Size為臨時文件大小,將Size打包成ID為0x74的報文發送給服務器端,服務器端根據報文內容控制下載進度,完成文件下載。
備份升級模塊流程設計如圖5所示。如圖5可知,為避免軟件升級失敗或引起安全事故,先判斷車輛狀態是否滿足升級條件,不滿足條件的調整車輛狀態,車輛狀態應為發動機轉速為0,車速為0,駐車制動開啟狀態,擋位為P擋,剩余電量應大于標定最低電量;車輛狀態滿足升級條件后將之前軟件目錄內的文件壓縮備份,并將壓縮包命名為原版軟件版本號,解壓新版軟件包,覆蓋原版軟件目錄;設置Linux系統自啟動腳本并重啟系統,系統重啟后運行新版軟件包內的install.sh,運行完后更名為installed.sh;若軟件升級失敗,先解壓原版軟件備份并覆蓋原版軟件目錄,再重啟運行原版軟件目錄內的installed.sh,提高軟件升級過程的安全性和可靠性。

圖5 備份升級模塊流程
通過Qt Creator,采用多線程機制,設計服務器端界面。主線程負責更新界面信息,子線程負責與控制器端進行信息傳輸,主線程與子線程之間通過信號槽機制傳輸信息,保證程序穩定性。定義一個類保存控制器端的通信進度和狀態,同時為正在通信的控制器端建立子類,保證不同控制器端的通信互不相擾。服務器端界面設計如圖6所示。
由圖6可知:服務器端界面分為控制器端列表區、通信信息狀態區和調試控制區;控制器端列表區包括新建控制器端ID、通信時IP地址、端口號、通信狀態和下載進度條;通信信息狀態區將通信過程中的主要信息顯示在新建的文本列表中;調試控制區包含ID、IP和端口號文本框,文本框中包含“開啟調試、發送命令和結束調試”按鍵,同時可顯示選中的控制器端信息。為指定控制器端更新軟件包時,鼠標右鍵單擊控制器端ID,并單擊選擇的軟件包;控制器端與服務器端建立聯系時,控制器端列表區顯示通信目標的IP和端口號,通信狀態為“上線”;鼠標單擊控制器端列表區可選中對應控制器端,調試控制區顯示被選中的控制器端信息,點擊“開啟調試”按鍵后,控制器端完成通信后,進入命令行調試模塊;調試時,先鍵入調試命令,點擊“發送命令”按鍵發送;結束調試時,點擊“結束調試”按鍵,進入文件下載模塊。

圖6 服務器端界面
通過電腦上傳測試軟件包、發布控制器端升級任務;遠程操控公網IP的云服務器,實現服務器端部署,并在服務器端界面上實時顯示升級過程中的關鍵信息;控制器端連接顯示器,通過4G模塊與互聯網建立通信,實時顯示升級進度,混動商用車巡航控制器OTA系統測試步驟如下。
1)開啟服務器端,設置ID為12345678的控制器端升級軟件包,選擇命令行調試,打開控制器端程序,與服務器端建立通信并開始測試。
2)OTA系統自動進入握手模塊,服務器端顯示數字證書驗證通過、密鑰發送成功、成功解密、控制器端版本號1.0.0等提示,隨后自動進入命令行調試模塊。
3)服務器端連續2次顯示“請求調試命令”的提示后,在服務器端界面鍵入“./test”調試命令,并點擊“發送命令”按鈕,顯示發送的調試命令和命令執行結果。
4)點擊“結束調試”按鍵,控制器端顯示可用更新版本,并詢問是否升級,輸入“y”后,服務器端顯示用戶同意,開始下載,進度條顯示下載進度;下載過程中強制關閉控制器,并重新打開繼續升級,服務器端下載進度條從上次中斷處開始,表示實現了斷點續傳功能;下載完成后,服務器端顯示發送哈希值,進行校驗。
5)校驗完成后,控制器端顯示校驗通過,提示手剎未拉緊,將手剎拉緊后,顯示滿足條件;控制器端顯示備份完成,重啟系統,自動打開命令行窗口,運行install.sh;運行完畢后,控制器端顯示安裝成功和測試成功,并要求用戶重啟系統;重新運行install.sh,并人為造成測試失敗,控制器端提示回滾,解壓完備份文件后,運行備份文件中的installed.sh,確認是否安裝成功;若軟件安裝成功,提示回滾到版本1.0.0,否則重新運行installed.sh。
以上測試顯示該系統能滿足混動商用車巡航控制器的遠程升級和調試,實現斷點續傳和回滾重刷,保證了網絡波動時軟件包的完整性,解決了控制器調試繁瑣的問題。
1)混動商用車巡航控制器OTA升級,實現了基于UPD協議的在線升級,同時對控制器開發階段的調試工作提供了解決方案。
2)OTA系統中通信模塊完成報文傳輸,握手模塊完成通信加密,命令行調試模塊完成命令調試,下載模塊完成軟件包傳輸,備份升級模塊完成軟件的升級和備份。
3)OTA系統設計時,通過對報文進行加密和CRC校驗,對下載文件進行哈希校驗,確保升級過程中數據的安全。