韋忠杰
(柳州市華創汽車設計有限公司,廣西 柳州 545616)
車機端的開發主要分為主處理器(SOC)與微控制器(MCU)的開發,其中SOC負責人機交互及相關功能實現(基于Android系統、Linux系統、WinCE等系統),MCU主要負責車機電源管理與整車控制器域網(CAN)數據收發。MCU為SOC提供車輛信息,SOC對車輛信息處理后提供服務,二者間正常通信是提供服務的基礎,CAN數據與整車電源變動的信息是被動獲取的,因此二者間的通信連接需要處于長連接狀態,以保證數據的及時響應與處理。
車機SOC與MCU一般通過通用異步收發傳輸器(UART)/串行外設接口(SPI)進行長連接數據傳輸,在此過程中數據處理不完善、通信中出現異常、不能及時處理等問題均會導致車機功能異常,因此良好的通信處理流程和通信鏈路狀態的檢測及恢復是非常重要的。
長連接通信需要對端與端的連接進行維護,同時增加連接的保活機制及異常檢測與處理。以UART為例進行長連接通信的數據傳輸作為研究對象進行解析。
在SOC與MCU的長連接過程中,存在SOC向MCU主動發送請求的情況,也存在MCU主動向SOC發送信息的情況,雙方都需要進入通信收發準備,并進行通信收發處理及通信狀態同步。
在SOC與MCU的長連接過程中,通信準備需要雙方都打開通信接口,共同完成通信參數設置。如果二者通過UART進行通信,則雙方需要進行以下操作:① 打開指定UART端口;② 設置波特率(需要雙方設置相同參數);③ 設置數據位(需要雙方設置相同參數,一般設為8 bit);④ 設置停止位(需要雙方設置相同參數);⑤ 設置奇偶校驗位(需要雙方設置相同參數)。
通信參數設置完畢后,即可進行數據通信。通信流程主要分為數據發送與數據接收,其中數據發送是主動觸發的,數據接收是被動獲取的,需要分開進行處理。數據發送與數據接收流程如圖1所示。

圖1 數據發送與數據接收流程
由于頻繁的通信交互會產生大量數據,需要防止通信過程中數據遺漏或被覆蓋,因此數據收發后需要及時處理,數據發送完成后再進行刪除。
通信數據的發送與接收處理流程如圖2所示。

圖2 數據發送與接收處理流程
通信數據的接收處理考慮到數據完整性及主線程響應慢的情況,主要分為以下2個步驟:① 將收到的數據拷貝到特定數組中,并與數組中已有數據進行拼接,拼成完整的數據幀供后續處理。由于同一時間發送數據較多,所以可能會出現數據分開多次發送的情況。② 特定線程對數組中的數據進行數據幀解析,從數據幀解析出有效數據,并將有效數據發給主線程進行處理,同時從數組中刪除相應的幀數據。由于數據解析處理耗時,因此需要放到其他線程處理,防止主線程阻塞響應慢的情況。
通信數據的發送處理分為數據打包與數據發送,主要分為以下2個步驟:① 根據收到的信息將要發送的數據進行打包,并將打包好的數據幀放入信息鏈表中,防止數據遺漏發送或數據覆蓋情況;② 特定線程對信息鏈表進行檢測,檢測到有信息時,則從信息鏈表中獲取數據幀進行發送,發送完后將對應的數據幀從信息鏈表中刪除。因信息鏈表循環檢測與數據的發送比較耗時,為防止主線程阻塞響應慢的情況,需要放到其他線程中進行處理。
在進行數據通信前,需要做好通信準備并同步連接狀態后,才能進行有效的數據傳輸。如果SOC在啟動過程中存在電壓不穩的情況,可能會出現干擾數據通過鏈路傳輸給MCU端,如果不進行狀態同步,則可能會導致異常情況出現。
SOC與MCU間的關系類似于網絡通信中的客戶端與服務端。MCU作為服務端需要確認與客戶端的連接情況,決定是否向客戶端發送數據及響應客戶端發送的數據;SOC作為客戶端,與服務端進行正式的數據通信前,需要先發送一串連接數據幀,告知服務端通信已準備好并進行連接,服務端收到數據并解析出連接數據幀后,反饋給客戶端,可以開始進行數據通信。通信狀態同步流程如圖3所示。

圖3 通信狀態同步流程
由于SOC與MCU間一直處于連接通信狀態,不需要同步斷開通信的情況,只有在機器休眠或關機的過程中才會斷開,休眠喚醒或重啟后MCU端會將連接狀態清除,并重新等待SOC的連接數據幀,SOC需要重新設置參數,并發送數據連接幀進行通信。
在整個通信周期中,可能有較長一段時間雙方是沒有交互的,在這過程中可以通過“心跳”機制判斷通信鏈路狀態。
“心跳”機制是指定時發送一個簡短的數據包,檢測連接是否正常。客戶端應用層使用定時器,定時向服務端發送一個簡短的數據包,然后等待服務端回應,如果在一定時間內沒有收到服務端回應,則認為是連接異常;同時,服務端在已連接的情況下,收到客戶端的“心跳”數據包后,及時應答對應數據包,如果固定時間內未收到“心跳”數據包,則認為連接異常。
如果服務端和客戶端有頻繁的數據通信往來,這些數據包本身就可以用于檢測連接情況,無須一直定時發送“心跳”數據包來增大通信數據量,因此可以將“心跳”數據包與正常數據包結合起來使用。優化后的“心跳”機制流程如圖4所示。① 客戶端設置一個定時器,用于定時發送“心跳”數據包;② 客戶端需要判斷信息鏈表中待發送的數據幀是否發送完畢歸零,發送完畢后則將計時器歸零后并啟動定時器開始計時;③ 客戶端如果在定時器運行計時過程中有新的數據幀要發送,則將定時器暫停;④ 客戶端發送數據幀后,一定時間內未收到服務端反饋的處理信息,計時時間到后則認為通信鏈路異常;⑤ 服務端設置一個定時器,用于確認通信鏈路狀況;⑥ 服務端每次接收到客戶端的數據幀后,則將定時器中的計時器重新歸零處理,且將每次處理的結果反饋給客戶端;⑦ 如果服務端一定時間內未收到來自客戶端的信息,計時時間到后則認為通信鏈路異常,并停止服務,等待服務端重新連接。

圖4 優化后的長連接“心跳”機制
根據長連接通信的內容已經可以讓雙方進行數據通信,并對數據的收發進行處理,而長連接“心跳”機制則能更進一步協助雙方進行通信鏈路狀態的檢測,從而及時發現通信鏈路異常并進行簡單的斷開處理。
但僅靠檢測到異常就進行斷開處理并不是最佳處理方法。需要對通信鏈路嘗試修復,從而繼續提供服務,且在異常出現時,將發送的數據進行保存,然后進行重發,即要求具有數據重發機制,防止重要數據的遺漏。因此,在上述的長連接通信與“心跳”機制上增加通信重連功能與數據重發機制,可讓長連接通信更加可靠。
通信重連就是將原有的鏈路端口關閉后重新打開,設置初始參數后,重新進行狀態的同步操作。在長連接通信過程中可能會出現異常且不可逆轉的情況,需要通過通信重連功能恢復通信,一般發生以下情況時需要通信重連:① 硬件設計缺陷導致偶發的電磁干擾,電磁干擾可能導致正在傳輸的數據遺失或導致鏈路異常,如果只影響一瞬間則可以通過數據重發機制解決,否則需要通過通信重連進行處理;② 通信客戶端軟件異常,例如數據能發送成功但接收不到服務端反饋的數據,一定時間后則需要重連來恢復通信狀態,并重新向服務端發送數據;如果進程異常,則需要重啟進程后再重連,這種情況下會導致短時間內的通信斷開,存在數據丟失的情況;③ 通信服務端軟件異常,如果能收到數據但不能發送數據,需要服務端處理異常后重連恢復通信狀態,然后向客戶端回饋數據。
長連接過程中出現異常,一般處理后都需要通過數據重發機制來維持之前通信狀態,確保數據完整性并進行響應。數據重發機制主要由2個部分組成,即發送數據幀的保存與刪除,重發次數及時間間隔。
可對“從信息鏈表中獲取數據幀發送給遠端后立即刪除數據幀”的流程進行修改,改為“從信息鏈表中獲取數據幀發送給遠端,待收到遠端的相應反饋后,再從信息鏈表中刪除相應的數據幀”。
重發次數可根據具體功能要求而定,一般設置3次,如果發送3次都未收到反饋,則基本可以認為通信連接異常。關閉通信連接并重新設置連接通信,發送次數重新統計。時間間隔可設為固定,也可將重發時間間隔逐漸加大,如設置為200 ms、400 ms、800 ms。
整個長連接通信的實現按軟件功能可分為數據發送、數據接收、通信狀態檢測和異常處理4個部分。由于客戶端與服務端框架大致相同,再次對客戶端通信流程進行分析,如圖5所示。由圖5可知該框架流程的軟件實現涉及到數組、鏈表、線程、線程同步與定時器的使用。各功能大體流程如下:

圖5 客戶端通信流程
(1) 主線程。接收應用數據后將數據打包放入待發送鏈表中,同步通知數據發送線程;監聽接收到服務端數據,將數據放入數組中進行拼接,然后同步通知數據接收處理線程。
(2) 數據發送。線程中判斷發送鏈表是否有數據,如果發送鏈表有數據,則獲取數據進行發送,取消定時“心跳”機制,并啟動服務端返回狀態檢測機制,如果一定時間未檢測到數據返回,則進入數據重發;如果發送鏈表無數據,則啟動定時器進入“心跳”模式,定時發送數據。
(3) 數據接收處理。線程從數組中解析出數據幀,進行數據解析后,刪除數組中獲取的數據幀并刪除發送鏈表中的數據,通知發送線程繼續進行下一幀數據的發送。
(4) 通信狀態檢測。數據發送線程發送數據后,啟動定時器確認一段時間內是否有數據反饋。如果數據接收處理線程中檢測到有對應數據返回,則同步取消定時器;如果沒有對應數據返回,則認為通信異常。
(5) 異常處理。一定時間內接收不到返回數據,則觸發重發機制,如果重發3次都不能接收到數據,則認為通信異常不可恢復,需要重新進行通信設置連接。
本文提供了一種車機內部SOC與MCU的長連接通信軟件的實現方式,在滿足基本通信功能的基礎上,根據長連接特性增加了通信狀態檢測、數據重發、通信重連及“心跳”機制,盡可能地保證長連接通信的有效性。