(電子科技大學 電子科學技術研究院,四川 成都 611731)
FlexRay總線是為滿足日益增長的車載網絡通信需求而制定的下一代車載總線標準,與現行的CAN總線相比,其優勢主要體現在通信速率、可靠性、安全性和靈活性4個方面。
FlexRay節點的結構符合ISO/OSI分層模型,包括第1層(物理層)、第2層(數據鏈路層)和第7層(應用層)[1]。其中,FlexRay標準定義了物理層和數據鏈路層的相關內容,物理層規定了FlexRay總線機械、電氣等要求,鏈路層規定了幀結構、幀傳輸方式、時鐘同步等問題[2]。對于應用層協議并沒有做詳細規定,只規定了通信循環的最長持續時間、每個時隙的最大有效負載等限制參數。因此,網絡設計者需要根據FlexRay網絡中傳輸的消息,配置合適的協議參數,以優化網絡通信性能。
FlexRay靜態時隙長度是影響FlexRay網絡靜態段通信性能的重要參數。目前,對靜態段時隙長度配置的研究主要從消息封裝優化算法的角度入手,旨在提高網絡帶寬利用率[3-7]。文獻[3]基于消息優先級將多個消息封裝進同一個靜態幀中并進一步引入時隙復用機制,同一靜態時隙在不同的通信周期內所傳輸的消息是可變的;文獻[4]和文獻[5]分別從不同的角度設計消息封裝策略,其中,文獻[4]將具有相同周期和來自相同節點的信號優先封裝進同一靜態幀,文獻[5]則將同一個節點內編號成整數倍關系的消息封裝到一個幀中。消息分割法是一種通過將負載較大的消息分割為多個子消息以優化靜態段參數的FlexRay靜態段消息封裝策略,文獻[6]將長消息分割,并將子消息填充到被分配短消息的時隙內;文獻[7]將長消息分割為多個子消息在靜態段傳輸,并進一步對消息分割的標準進行分析,得出總線負載率隨消息分割大小的變化曲線。
上述研究均在理論上對FlexRay消息封裝策略進行設計優化,對于算法在應用上的實現方法則鮮有論述。因此,從應用層的角度,設計了一種基于消息分割策略的FlexRay總線靜態段傳輸實現方法,保證發送端不同長度消息的準確傳輸以及接收端數據的順序性和完整性,并搭建實驗平臺驗證設計的可行性。
FlexRay的通信是基于“通信循環”實現的。通信循環是周期性的,且持續時間相等,因此也稱為通信周期。一個通信循環被依次分為靜態段、動態段、符號窗口和網絡空閑時間4個部分[8],如圖1所示。其中,靜態段的長度一般占整個通信循環的70%以上[9];動態段和符號窗口不是必須的;網絡空閑時間用于時鐘同步,保證通信控制器在最壞情況下,能夠有足夠的時間計算相位修正值和頻率修正值,并能進行相位的修正。

圖1 FlexRay通信周期
靜態段是由靜態時隙(Static Slot)組成的,所有靜態時隙的持續時間相同。靜態段采用全局時分多路訪問型操作原理進行媒體訪問控制[10],網絡中各節點只在被分配給它的靜態時隙內有權向總線中發送數據。為便于分配,靜態時隙從1開始依次編號,記為時隙ID。每個靜態時隙只屬于一個節點,但每個節點可以被分配最多16個時隙。這些概念均被協議參數化,由網絡設計者離線配置。
靜態段消息傳輸時間具有可預測型,一般用于傳輸對實時性要求比較高的報文,同時,靜態段適合基于時間觸發的報文,即在一個發送時隙到來時,無論被分配到該時隙發送的報文是否被更新,都將該報文發送到總線。
在協議運行過程中,消息被封裝成FlexRay數據幀在總線上傳輸。FlexRay幀格式如圖2所示,包括頭部段、負載段和尾部段3個部分。頭部段包含5 bits指示位、11 bits幀ID、7 bits負載長度、11 bits頭部循環冗余校驗碼和6 bits周期計數;負載段可包含0~254 B的數據;尾部段含有24 bits尾部循環冗余校驗碼。

圖2 FlexRay靜態幀格式及封裝方式
幀ID字段指示了傳輸該幀的時隙,即時隙ID。有效數據負載段保存至多254個字節的有效數據,該段的長度由有效負載長度字段指定。在靜態段,所有幀的有效負載長度都是固定的。尾部段是一個3 B的CRC,用于校驗前面的數據域傳輸是否正確,它的長度是頭部端的字長加上有效負載數據段的字長。
邏輯數據要在物理層進行傳輸,必須要借助傳輸保護和預防措施對其進行傳輸封裝,以消除傳輸媒介的影響。FlexRay以字節為單位進行封裝,如圖2所示,在幀起始、幀結尾和每個字節前加上特殊符號。
FlexRay協議規定,靜態時隙的時間長度由總線比特率和最長數據幀決定,靜態段時隙的長度至少是靜態段傳輸最長幀所需的時間加上集群內任一控制器處理的最長時間和時間精度的持續時間以及時隙延時校正參數的最大值[11]。由此可見,在配置靜態時隙長度時,起決定作用的是靜態段傳輸的最長幀所需時間。實際網絡設計中,在一個靜態幀只傳輸一則消息的前提下,這種時隙配置方式會降低總線帶寬利用率。以圖3為例,靜態段以幀c的長度被分為10個靜態時隙,可以發現,只有c充分利用了帶寬,而e對帶寬資源的浪費是網絡設計者和使用者都無法容忍的。

圖3 靜態段時隙分配方案示例
本例所示時隙分配模型參考汽車工程師協會提供的FlexRay消息基準數據,具有一定的代表性。因此,針對根據網絡最長幀配置靜態段協議參數的缺陷,出現了一種稱為消息分割法的消息封裝策略。消息分割算法的核心思想是對長消息進行拆分,平衡消息的負載長度,并以此配置合適的靜態時隙長度,以達到提高FlexRay總線帶寬利用率的目的。
如圖4所示,對于根據消息a負載長度配置時隙參數的FlexRay靜態段通信來說,消息f封裝成的數據幀顯然無法在一個靜態時隙內傳輸,因此,將其按照貪心策略分割為f1~f4 4個子消息,依序在4個連續通信周期的相同時隙內傳輸。
FlexRay靜態段通信機制可以保證消息在總線上傳輸的順序性,但無法保證連續通信周期內同一時隙中的消息在空間上的連續性。因此,利用消息分割算法封裝的消息,還需要在接收端對其進行拼接。一種消息提交策略是定義一個由多個連續通信周期組成的信息交互周期[11],在信息交互周期內接收到的消息,在最后一個通信周期結束時,一并提交給接收端CPU。但是該方式會使消息得到處理的時間推遲到整個信息交互周期結束,影響了FlexRay消息的實時性。由此,提出一種消息分類處理的消息分割策略實現方式,利用FlexRay靜態幀負載段首字節作為標志字段,以區分未分割消息和已分割消息。該字節前4位用于指示消息是否被分割,后4位用于指示該消息是否為被分割消息的最后一個子消息。發送端根據消息長度填充分割標志字段,接收端根據標志字段決定對消息的處理方式。為未分割消息和已分割消息配置不同的接收緩沖區,對于前者,可直接提交給CPU;對于后者,在完成所有子消息的接收后,對消息負載數據進行拼接,再一并提交。通過這種二級緩沖的機制,與基于信息交互周期的消息分割策略相比,提高了未分割消息的實時性。

圖4 消息分割法
基于本設計,消息在封裝成FlexRay幀時,會產生額外協議開銷。額外協議開銷的來源有兩個:① 數據負載段首字節的標志字段;② 對于被分割的消息,新增的消息幀會增加額外協議開銷。協議開銷的增長取決于靜態幀負載段長度和消息負載長度。
由表1可以發現,負載段長度增大會在一定程度上導致總線帶寬利用率的下降,但是減少了消息分割所產生的新FlexRay靜態幀的個數,而額外協議開銷主要來源于對新數據幀的封裝。同時,負載段長度過大則會使帶寬利用率嚴重下降,失去了消息分割的意義。因此,將FlexRay靜態幀負載段長度定義為16 B。
根據前文對FlexRay靜態幀格式和編碼方式的分析,對于負載段長度為jbits的FlexRay靜態幀,其長度可以表示為[12]

表1 不同負載段長度的額外協議開銷與帶寬利用率
LFL(j)=TSS+FSS+80+20wj+FES
(1)
式中,TSS、FSS和FES在圖2中已說明,80為幀頭和幀尾編碼后所占位數;wj為以字為單位的有效負載長度。由此,FlexRay靜態時隙的長度可以表示為

(2)
式中,TAPO為靜態時隙的動作點偏移;gdBit為傳輸1 bit所需時間;CID為空閑通道定界符;TMT為宏節拍持續時間。
FlexRay網絡參數取表2中各值,可得靜態時隙長度LST的值為112 μs。故將靜態時隙長度配置為120個宏節拍,即120 μs。靜態段內靜態時隙個數為20個,網絡空閑時間占30個宏節拍,整個通信周期持續時間為2.43 ms,小于協議規定最大通信周期長度16 ms。

表2 FlexRay網絡參數
FlexRay數據收發通過中斷觸發。MC9S12XF512單片機內集成FlexRay模塊,提供獨立的中斷源。節點的每一個時隙均與片內的一個Message Buffer對應。Message Buffer是FlexRay模塊中一塊連續的存儲區域,被抽象成存儲幀的數據結構[13]。在程序初始化階段,為被使用的MB設置類型,并為其設置一個中斷服務程序。當通信循環到達指定時隙時,即FlexRay模塊系統時鐘運行到該時隙的動作點處,對應MB的時隙狀態信息被更新,Message Buffer中斷標志位被置位,觸發對應中斷,執行中斷服務程序。
2.3.1 FlexRay通信程序設計
通信程序基于μC/OS嵌入式系統中的任務進行管理,主要包括FlexRay收發任務和數據處理任務,其中數據處理任務負責將總線數據通過串口發送到PC上。所有任務均阻塞在μC/OS任務信號量等待,等待中斷服務程序發布信號量將其喚醒。
FlexRay發送任務和FlexRay接收任務共同維護一個時隙映射表,時隙映射表中元素為保存有每個時隙中待處理的消息的鏈表的頭節點,該節點儲存有鏈表結構信息。
typedef struct {
slotListNode_t *start;
slotListNode_t *end;
slotType type;
} listHead;
程序利用μC/OS內存管理接口開辟一塊內存池。對于發送時隙,其對應鏈表中節點儲存的是待發送的消息;對于接收時隙,節點中儲存接收到的被分割的子消息。節點中的數據域指針指向一塊從內存池中申請的內存塊。內存塊大小都是16 B,因此在待發送消息入鏈時就需要對其以15 B為標準進行分割。
struct slotListNode_s {
unsigned char *frMsg;
struct slotListNode_s *pNext;
};
typedef struct slotListNode_s slotListNode_t;
FlexRay發送任務從對應時隙的消息鏈表中取出頭節點后第一個節點中的數據(如果消息鏈表不為空),填充分割標志位后調用Fr_transmit_data函數發送,并將該節點從消息鏈表中移除。

圖5 發送任務流程
typedef struct {
unsigned char base[512];
unsigned char front;
unsigned char rear;
unsigned char size;
} circularBuffer;
FlexRay接收任務在被喚醒后,調用接收函數Fr_receive_data讀取MB中數據。Fr_receive_data函數是FlexRay驅動函數,對該函數進行修改,添加參數uint8 *split區分接收到的數據是否是完整的一條消息。對于未被分割的消息,直接將其數據寫入到待處理隊列circularBuffer;對于被分割的消息,將數據暫存在該時隙對應的消息鏈表中,待接收到全部子消息后一并寫入待處理隊列。

圖6 接收任務流程
數據處理任務在收到CPU發布的信號后,從待處理隊列中取出消息數據交由串口發送。
2.3.2 利用XGATE協處理器管理串口發送
為了提高程序執行效率,降低系統因中斷而產生的實時性問題,采用XGATE處理串口通信。XGATE是一個獨立于主CPU (S12X)的可編程RISC內核,用以提高應用程序的反應速度,減少主CPU的中斷負荷。XGATE由中斷驅動,可以獨立于CPU運行中斷服務程序。XGATE與CPU之間,可以通過共享變量進行通信[14]。
用XGATE處理串口通信,XGATE與S12X CPU之間采用雙緩沖機制進行通信。XGATE將buf1中數據發送到串口緩沖區后,向CPU提交中斷請求;CPU中斷服務程序交換緩沖區,向數據處理任務發布信號,并重新置位串口發送中斷。此時,XGATE繼續通過串口發送數據,CPU執行數據處理任務。數據處理任務被喚醒后,將待處理隊列中的數據拷貝到buf2中。
使用集成有FlexRay通信控制器的MC9S12XF512型單片機作為主控芯片,與總線收發器TJA1080組成通信節點,并搭建一個雙節點簡易通信網絡,節點結構如圖5所示,FlexRay網絡結構如圖6所示。

圖7 FlexRay節點結構

圖8 FlexRay網絡結構
實驗參數配置如表3所示,Node 2通過串口將FlexRay總線數據提交給PC。

表3 靜態段時隙分配
經過實驗,程序運行穩定,通過串口助手觀察實驗數據。節點1在時隙7中在3個周期內發送的長消息在節點2中成功接收并實現拼接。
分析了基于消息分割策略的FlexRay總線靜態段消息封裝方式,提出了一種基于消息分類處理的消息分割策略實現方式,在此基礎上對FlexRay應用層進行設計,通過對消息分割所產生協議開銷和帶寬利用率進行分析,確定FlexRay靜態段協議參數,并在μC/OS系統上實現了基于該設計的FlexRay通信系統。本設計在保證帶寬利用率和消息傳輸延遲的同時,滿足了不同長度消息在靜態段上的可靠傳輸,并具有一定可擴展性。最后,利用MC9S12XF512單片機搭建FlexRay網絡,實驗驗證程序設計可行性。