(電子科技大學 電子科學技術研究院,四川 成都 611731)
FlexRay總線是為滿足日益增長的車載網(wǎng)絡通信需求而制定的下一代車載總線標準,與現(xiàn)行的CAN總線相比,其優(yōu)勢主要體現(xiàn)在通信速率、可靠性、安全性和靈活性4個方面。
FlexRay節(jié)點的結構符合ISO/OSI分層模型,包括第1層(物理層)、第2層(數(shù)據(jù)鏈路層)和第7層(應用層)[1]。其中,F(xiàn)lexRay標準定義了物理層和數(shù)據(jù)鏈路層的相關內(nèi)容,物理層規(guī)定了FlexRay總線機械、電氣等要求,鏈路層規(guī)定了幀結構、幀傳輸方式、時鐘同步等問題[2]。對于應用層協(xié)議并沒有做詳細規(guī)定,只規(guī)定了通信循環(huán)的最長持續(xù)時間、每個時隙的最大有效負載等限制參數(shù)。因此,網(wǎng)絡設計者需要根據(jù)FlexRay網(wǎng)絡中傳輸?shù)南?,配置合適的協(xié)議參數(shù),以優(yōu)化網(wǎng)絡通信性能。
FlexRay靜態(tài)時隙長度是影響FlexRay網(wǎng)絡靜態(tài)段通信性能的重要參數(shù)。目前,對靜態(tài)段時隙長度配置的研究主要從消息封裝優(yōu)化算法的角度入手,旨在提高網(wǎng)絡帶寬利用率[3-7]。文獻[3]基于消息優(yōu)先級將多個消息封裝進同一個靜態(tài)幀中并進一步引入時隙復用機制,同一靜態(tài)時隙在不同的通信周期內(nèi)所傳輸?shù)南⑹强勺兊?;文獻[4]和文獻[5]分別從不同的角度設計消息封裝策略,其中,文獻[4]將具有相同周期和來自相同節(jié)點的信號優(yōu)先封裝進同一靜態(tài)幀,文獻[5]則將同一個節(jié)點內(nèi)編號成整數(shù)倍關系的消息封裝到一個幀中。消息分割法是一種通過將負載較大的消息分割為多個子消息以優(yōu)化靜態(tài)段參數(shù)的FlexRay靜態(tài)段消息封裝策略,文獻[6]將長消息分割,并將子消息填充到被分配短消息的時隙內(nèi);文獻[7]將長消息分割為多個子消息在靜態(tài)段傳輸,并進一步對消息分割的標準進行分析,得出總線負載率隨消息分割大小的變化曲線。
上述研究均在理論上對FlexRay消息封裝策略進行設計優(yōu)化,對于算法在應用上的實現(xiàn)方法則鮮有論述。因此,從應用層的角度,設計了一種基于消息分割策略的FlexRay總線靜態(tài)段傳輸實現(xiàn)方法,保證發(fā)送端不同長度消息的準確傳輸以及接收端數(shù)據(jù)的順序性和完整性,并搭建實驗平臺驗證設計的可行性。
FlexRay的通信是基于“通信循環(huán)”實現(xiàn)的。通信循環(huán)是周期性的,且持續(xù)時間相等,因此也稱為通信周期。一個通信循環(huán)被依次分為靜態(tài)段、動態(tài)段、符號窗口和網(wǎng)絡空閑時間4個部分[8],如圖1所示。其中,靜態(tài)段的長度一般占整個通信循環(huán)的70%以上[9];動態(tài)段和符號窗口不是必須的;網(wǎng)絡空閑時間用于時鐘同步,保證通信控制器在最壞情況下,能夠有足夠的時間計算相位修正值和頻率修正值,并能進行相位的修正。
圖1 FlexRay通信周期
靜態(tài)段是由靜態(tài)時隙(Static Slot)組成的,所有靜態(tài)時隙的持續(xù)時間相同。靜態(tài)段采用全局時分多路訪問型操作原理進行媒體訪問控制[10],網(wǎng)絡中各節(jié)點只在被分配給它的靜態(tài)時隙內(nèi)有權向總線中發(fā)送數(shù)據(jù)。為便于分配,靜態(tài)時隙從1開始依次編號,記為時隙ID。每個靜態(tài)時隙只屬于一個節(jié)點,但每個節(jié)點可以被分配最多16個時隙。這些概念均被協(xié)議參數(shù)化,由網(wǎng)絡設計者離線配置。
靜態(tài)段消息傳輸時間具有可預測型,一般用于傳輸對實時性要求比較高的報文,同時,靜態(tài)段適合基于時間觸發(fā)的報文,即在一個發(fā)送時隙到來時,無論被分配到該時隙發(fā)送的報文是否被更新,都將該報文發(fā)送到總線。
在協(xié)議運行過程中,消息被封裝成FlexRay數(shù)據(jù)幀在總線上傳輸。FlexRay幀格式如圖2所示,包括頭部段、負載段和尾部段3個部分。頭部段包含5 bits指示位、11 bits幀ID、7 bits負載長度、11 bits頭部循環(huán)冗余校驗碼和6 bits周期計數(shù);負載段可包含0~254 B的數(shù)據(jù);尾部段含有24 bits尾部循環(huán)冗余校驗碼。
圖2 FlexRay靜態(tài)幀格式及封裝方式
幀ID字段指示了傳輸該幀的時隙,即時隙ID。有效數(shù)據(jù)負載段保存至多254個字節(jié)的有效數(shù)據(jù),該段的長度由有效負載長度字段指定。在靜態(tài)段,所有幀的有效負載長度都是固定的。尾部段是一個3 B的CRC,用于校驗前面的數(shù)據(jù)域傳輸是否正確,它的長度是頭部端的字長加上有效負載數(shù)據(jù)段的字長。
邏輯數(shù)據(jù)要在物理層進行傳輸,必須要借助傳輸保護和預防措施對其進行傳輸封裝,以消除傳輸媒介的影響。FlexRay以字節(jié)為單位進行封裝,如圖2所示,在幀起始、幀結尾和每個字節(jié)前加上特殊符號。
FlexRay協(xié)議規(guī)定,靜態(tài)時隙的時間長度由總線比特率和最長數(shù)據(jù)幀決定,靜態(tài)段時隙的長度至少是靜態(tài)段傳輸最長幀所需的時間加上集群內(nèi)任一控制器處理的最長時間和時間精度的持續(xù)時間以及時隙延時校正參數(shù)的最大值[11]。由此可見,在配置靜態(tài)時隙長度時,起決定作用的是靜態(tài)段傳輸?shù)淖铋L幀所需時間。實際網(wǎng)絡設計中,在一個靜態(tài)幀只傳輸一則消息的前提下,這種時隙配置方式會降低總線帶寬利用率。以圖3為例,靜態(tài)段以幀c的長度被分為10個靜態(tài)時隙,可以發(fā)現(xiàn),只有c充分利用了帶寬,而e對帶寬資源的浪費是網(wǎng)絡設計者和使用者都無法容忍的。
圖3 靜態(tài)段時隙分配方案示例
本例所示時隙分配模型參考汽車工程師協(xié)會提供的FlexRay消息基準數(shù)據(jù),具有一定的代表性。因此,針對根據(jù)網(wǎng)絡最長幀配置靜態(tài)段協(xié)議參數(shù)的缺陷,出現(xiàn)了一種稱為消息分割法的消息封裝策略。消息分割算法的核心思想是對長消息進行拆分,平衡消息的負載長度,并以此配置合適的靜態(tài)時隙長度,以達到提高FlexRay總線帶寬利用率的目的。
如圖4所示,對于根據(jù)消息a負載長度配置時隙參數(shù)的FlexRay靜態(tài)段通信來說,消息f封裝成的數(shù)據(jù)幀顯然無法在一個靜態(tài)時隙內(nèi)傳輸,因此,將其按照貪心策略分割為f1~f4 4個子消息,依序在4個連續(xù)通信周期的相同時隙內(nèi)傳輸。
FlexRay靜態(tài)段通信機制可以保證消息在總線上傳輸?shù)捻樞蛐?,但無法保證連續(xù)通信周期內(nèi)同一時隙中的消息在空間上的連續(xù)性。因此,利用消息分割算法封裝的消息,還需要在接收端對其進行拼接。一種消息提交策略是定義一個由多個連續(xù)通信周期組成的信息交互周期[11],在信息交互周期內(nèi)接收到的消息,在最后一個通信周期結束時,一并提交給接收端CPU。但是該方式會使消息得到處理的時間推遲到整個信息交互周期結束,影響了FlexRay消息的實時性。由此,提出一種消息分類處理的消息分割策略實現(xiàn)方式,利用FlexRay靜態(tài)幀負載段首字節(jié)作為標志字段,以區(qū)分未分割消息和已分割消息。該字節(jié)前4位用于指示消息是否被分割,后4位用于指示該消息是否為被分割消息的最后一個子消息。發(fā)送端根據(jù)消息長度填充分割標志字段,接收端根據(jù)標志字段決定對消息的處理方式。為未分割消息和已分割消息配置不同的接收緩沖區(qū),對于前者,可直接提交給CPU;對于后者,在完成所有子消息的接收后,對消息負載數(shù)據(jù)進行拼接,再一并提交。通過這種二級緩沖的機制,與基于信息交互周期的消息分割策略相比,提高了未分割消息的實時性。
圖4 消息分割法
基于本設計,消息在封裝成FlexRay幀時,會產(chǎn)生額外協(xié)議開銷。額外協(xié)議開銷的來源有兩個:① 數(shù)據(jù)負載段首字節(jié)的標志字段;② 對于被分割的消息,新增的消息幀會增加額外協(xié)議開銷。協(xié)議開銷的增長取決于靜態(tài)幀負載段長度和消息負載長度。
由表1可以發(fā)現(xiàn),負載段長度增大會在一定程度上導致總線帶寬利用率的下降,但是減少了消息分割所產(chǎn)生的新FlexRay靜態(tài)幀的個數(shù),而額外協(xié)議開銷主要來源于對新數(shù)據(jù)幀的封裝。同時,負載段長度過大則會使帶寬利用率嚴重下降,失去了消息分割的意義。因此,將FlexRay靜態(tài)幀負載段長度定義為16 B。
根據(jù)前文對FlexRay靜態(tài)幀格式和編碼方式的分析,對于負載段長度為jbits的FlexRay靜態(tài)幀,其長度可以表示為[12]
表1 不同負載段長度的額外協(xié)議開銷與帶寬利用率
LFL(j)=TSS+FSS+80+20wj+FES
(1)
式中,TSS、FSS和FES在圖2中已說明,80為幀頭和幀尾編碼后所占位數(shù);wj為以字為單位的有效負載長度。由此,F(xiàn)lexRay靜態(tài)時隙的長度可以表示為
(2)
式中,TAPO為靜態(tài)時隙的動作點偏移;gdBit為傳輸1 bit所需時間;CID為空閑通道定界符;TMT為宏節(jié)拍持續(xù)時間。
FlexRay網(wǎng)絡參數(shù)取表2中各值,可得靜態(tài)時隙長度LST的值為112 μs。故將靜態(tài)時隙長度配置為120個宏節(jié)拍,即120 μs。靜態(tài)段內(nèi)靜態(tài)時隙個數(shù)為20個,網(wǎng)絡空閑時間占30個宏節(jié)拍,整個通信周期持續(xù)時間為2.43 ms,小于協(xié)議規(guī)定最大通信周期長度16 ms。
表2 FlexRay網(wǎng)絡參數(shù)
FlexRay數(shù)據(jù)收發(fā)通過中斷觸發(fā)。MC9S12XF512單片機內(nèi)集成FlexRay模塊,提供獨立的中斷源。節(jié)點的每一個時隙均與片內(nèi)的一個Message Buffer對應。Message Buffer是FlexRay模塊中一塊連續(xù)的存儲區(qū)域,被抽象成存儲幀的數(shù)據(jù)結構[13]。在程序初始化階段,為被使用的MB設置類型,并為其設置一個中斷服務程序。當通信循環(huán)到達指定時隙時,即FlexRay模塊系統(tǒng)時鐘運行到該時隙的動作點處,對應MB的時隙狀態(tài)信息被更新,Message Buffer中斷標志位被置位,觸發(fā)對應中斷,執(zhí)行中斷服務程序。
2.3.1 FlexRay通信程序設計
通信程序基于μC/OS嵌入式系統(tǒng)中的任務進行管理,主要包括FlexRay收發(fā)任務和數(shù)據(jù)處理任務,其中數(shù)據(jù)處理任務負責將總線數(shù)據(jù)通過串口發(fā)送到PC上。所有任務均阻塞在μC/OS任務信號量等待,等待中斷服務程序發(fā)布信號量將其喚醒。
FlexRay發(fā)送任務和FlexRay接收任務共同維護一個時隙映射表,時隙映射表中元素為保存有每個時隙中待處理的消息的鏈表的頭節(jié)點,該節(jié)點儲存有鏈表結構信息。
typedef struct {
slotListNode_t *start;
slotListNode_t *end;
slotType type;
} listHead;
程序利用μC/OS內(nèi)存管理接口開辟一塊內(nèi)存池。對于發(fā)送時隙,其對應鏈表中節(jié)點儲存的是待發(fā)送的消息;對于接收時隙,節(jié)點中儲存接收到的被分割的子消息。節(jié)點中的數(shù)據(jù)域指針指向一塊從內(nèi)存池中申請的內(nèi)存塊。內(nèi)存塊大小都是16 B,因此在待發(fā)送消息入鏈時就需要對其以15 B為標準進行分割。
struct slotListNode_s {
unsigned char *frMsg;
struct slotListNode_s *pNext;
};
typedef struct slotListNode_s slotListNode_t;
FlexRay發(fā)送任務從對應時隙的消息鏈表中取出頭節(jié)點后第一個節(jié)點中的數(shù)據(jù)(如果消息鏈表不為空),填充分割標志位后調(diào)用Fr_transmit_data函數(shù)發(fā)送,并將該節(jié)點從消息鏈表中移除。
圖5 發(fā)送任務流程
typedef struct {
unsigned char base[512];
unsigned char front;
unsigned char rear;
unsigned char size;
} circularBuffer;
FlexRay接收任務在被喚醒后,調(diào)用接收函數(shù)Fr_receive_data讀取MB中數(shù)據(jù)。Fr_receive_data函數(shù)是FlexRay驅動函數(shù),對該函數(shù)進行修改,添加參數(shù)uint8 *split區(qū)分接收到的數(shù)據(jù)是否是完整的一條消息。對于未被分割的消息,直接將其數(shù)據(jù)寫入到待處理隊列circularBuffer;對于被分割的消息,將數(shù)據(jù)暫存在該時隙對應的消息鏈表中,待接收到全部子消息后一并寫入待處理隊列。
圖6 接收任務流程
數(shù)據(jù)處理任務在收到CPU發(fā)布的信號后,從待處理隊列中取出消息數(shù)據(jù)交由串口發(fā)送。
2.3.2 利用XGATE協(xié)處理器管理串口發(fā)送
為了提高程序執(zhí)行效率,降低系統(tǒng)因中斷而產(chǎn)生的實時性問題,采用XGATE處理串口通信。XGATE是一個獨立于主CPU (S12X)的可編程RISC內(nèi)核,用以提高應用程序的反應速度,減少主CPU的中斷負荷。XGATE由中斷驅動,可以獨立于CPU運行中斷服務程序。XGATE與CPU之間,可以通過共享變量進行通信[14]。
用XGATE處理串口通信,XGATE與S12X CPU之間采用雙緩沖機制進行通信。XGATE將buf1中數(shù)據(jù)發(fā)送到串口緩沖區(qū)后,向CPU提交中斷請求;CPU中斷服務程序交換緩沖區(qū),向數(shù)據(jù)處理任務發(fā)布信號,并重新置位串口發(fā)送中斷。此時,XGATE繼續(xù)通過串口發(fā)送數(shù)據(jù),CPU執(zhí)行數(shù)據(jù)處理任務。數(shù)據(jù)處理任務被喚醒后,將待處理隊列中的數(shù)據(jù)拷貝到buf2中。
使用集成有FlexRay通信控制器的MC9S12XF512型單片機作為主控芯片,與總線收發(fā)器TJA1080組成通信節(jié)點,并搭建一個雙節(jié)點簡易通信網(wǎng)絡,節(jié)點結構如圖5所示,F(xiàn)lexRay網(wǎng)絡結構如圖6所示。
圖7 FlexRay節(jié)點結構
圖8 FlexRay網(wǎng)絡結構
實驗參數(shù)配置如表3所示,Node 2通過串口將FlexRay總線數(shù)據(jù)提交給PC。
表3 靜態(tài)段時隙分配
經(jīng)過實驗,程序運行穩(wěn)定,通過串口助手觀察實驗數(shù)據(jù)。節(jié)點1在時隙7中在3個周期內(nèi)發(fā)送的長消息在節(jié)點2中成功接收并實現(xiàn)拼接。
分析了基于消息分割策略的FlexRay總線靜態(tài)段消息封裝方式,提出了一種基于消息分類處理的消息分割策略實現(xiàn)方式,在此基礎上對FlexRay應用層進行設計,通過對消息分割所產(chǎn)生協(xié)議開銷和帶寬利用率進行分析,確定FlexRay靜態(tài)段協(xié)議參數(shù),并在μC/OS系統(tǒng)上實現(xiàn)了基于該設計的FlexRay通信系統(tǒng)。本設計在保證帶寬利用率和消息傳輸延遲的同時,滿足了不同長度消息在靜態(tài)段上的可靠傳輸,并具有一定可擴展性。最后,利用MC9S12XF512單片機搭建FlexRay網(wǎng)絡,實驗驗證程序設計可行性。