引言
集成在微控制器芯片中的CAN總線通信引擎的外設(shè)電路系統(tǒng),有一些典型的實(shí)現(xiàn),例如飛思卡爾半導(dǎo)體(已并入恩智浦半導(dǎo)體)的ColdFire系列微控制器中用到的MSCAN和Kinetis系列微控制器的FlexCAN(由Silvaco International公司設(shè)計(jì)),這些CAN總線通信引擎在汽車電子應(yīng)用中已經(jīng)被廣泛使用,用以實(shí)現(xiàn)內(nèi)存中的數(shù)據(jù)與CAN總線上串行信號(hào)的的相互轉(zhuǎn)換。靈動(dòng)微電子設(shè)計(jì)生產(chǎn)的MM32F0140和MM32F5系列微控制器芯片也集成了FlexCAN外設(shè)模塊。本文以MM32F0140 / MM32F5270 微控制器芯片上集成的FlexCAN作為CAN硬件外設(shè)模塊的實(shí)例,講述硬件的CAN通信引擎的工作方式,以此展現(xiàn)硬件電路系統(tǒng)對(duì)CAN總線控制邏輯的建模,建立起軟件系統(tǒng)同硬件電路的關(guān)聯(lián)關(guān)系。同本系列的其它文章一樣,本文希望以盡量簡(jiǎn)潔的語言,關(guān)注基本的原理和常用的功能,建立起對(duì)常規(guī)CAN外設(shè)模塊的概念,為后續(xù)適配CAN通信協(xié)議棧的軟件包做好準(zhǔn)備。
硬件外設(shè)模塊
系統(tǒng)概要
FlexCAN外設(shè)模塊是CAN總線通信的協(xié)議引擎,通過一個(gè)非常靈活的郵箱管理系統(tǒng)(消息緩沖區(qū)MB)管理發(fā)送和接收CAN通信幀。郵箱管理系統(tǒng)由一組消息緩沖區(qū)Message Buffer組成,MB中存放了通信幀的配置信息、數(shù)據(jù)負(fù)載、時(shí)間戳、消息ID等。完整的FlexCAN外設(shè),在MB隊(duì)列中的前38個(gè)MB可以配置成FIFO模式,配合一個(gè)功能強(qiáng)大的ID過濾機(jī)制,可以將總線上捕獲到的輸入幀同一個(gè)ID過濾器表的項(xiàng)目進(jìn)行匹配(多達(dá)128個(gè)擴(kuò)展ID,或者256個(gè)標(biāo)準(zhǔn)ID,或者512個(gè)8位的ID片段),并且可以在獨(dú)立掩碼寄存器中選擇多達(dá)32個(gè)ID過濾器表項(xiàng)。
同時(shí)使用FIFO和獨(dú)立消息郵箱(單通道)接收幀亦是可行的。使用消息郵箱接收幀,就是將選定的MB同ID固定的消息ID綁定后,該MB僅能接收固定消息ID的通信幀,使用ID掩碼機(jī)制的情況下,可以將匹配一個(gè)范圍的ID。
在執(zhí)行發(fā)送幀或者接收幀之前,這里需要強(qiáng)調(diào)一個(gè)很重要的概念,當(dāng)說明一個(gè)MB處于激活(Active)狀態(tài)時(shí),在意味著它正在參與發(fā)送過程的仲裁或是接收過程中的匹配。此處的激活狀態(tài),其實(shí)就意味著這個(gè)MB當(dāng)前正被FlexCAN外設(shè)或CPU占用,它是不可操作的。
FlexCAN外設(shè)模塊內(nèi)部包含總線接口單元、發(fā)送機(jī)構(gòu)(包含仲裁)、接收機(jī)構(gòu)(包含匹配)、消息緩沖區(qū),以及協(xié)議引擎,有功能框圖如圖x所示。
figure-flexcan-block-diagram
圖x FlexCAN的系統(tǒng)框圖CPU通過外設(shè)總線訪問FlexCAN的寄存器,與FlexCAN外設(shè)進(jìn)行交互,除了通過寄存器配置FlexCAN模塊的多種工作模式及反饋信息外,CPU主要是向MB(消息緩沖區(qū))中寫入CAN通信幀的數(shù)據(jù)內(nèi)容。消息緩沖區(qū)的存儲(chǔ)塊中包含多個(gè)MB,每個(gè)MB對(duì)應(yīng)一個(gè)CAN通信幀內(nèi)容的數(shù)據(jù)結(jié)構(gòu),并且可分別配置為將要發(fā)送幀的MB或是準(zhǔn)備接收幀的MB。當(dāng)要發(fā)送幀時(shí),先將CAN發(fā)送幀的內(nèi)容(包括幀ID、數(shù)據(jù)負(fù)載等)按照MB的存儲(chǔ)結(jié)構(gòu)填充到特定的字段,然后配置MB中的CODE字段為發(fā)送命令,則協(xié)議引擎PE會(huì)自動(dòng)啟動(dòng)發(fā)送操作過程,包括自動(dòng)同總線上的其他設(shè)備進(jìn)行仲裁,以及在超過連續(xù)5個(gè)同電平位之后自動(dòng)翻轉(zhuǎn)等。當(dāng)要接收幀時(shí),需要從多個(gè)幀接收過濾器中拿出一個(gè),設(shè)定需要匹配接收幀的ID(或者一個(gè)范圍),并為之綁定一個(gè)存放將要匹配到的CAN通信幀數(shù)據(jù)內(nèi)容的MB,之后協(xié)議引擎PE會(huì)監(jiān)控CAN總線上的信號(hào)流,當(dāng)遇到匹配ID范圍內(nèi)的通信幀,就存下來到預(yù)先準(zhǔn)備好的MB。發(fā)送和接收完成后,協(xié)議引擎都會(huì)通過寄存器接口向CPU傳達(dá)狀態(tài)的變化,產(chǎn)生中斷觸發(fā)進(jìn)一步的數(shù)據(jù)搬運(yùn)過程。
PS:CAN總線對(duì)CAN通信幀進(jìn)行仲裁時(shí),不是以發(fā)送通信幀或接收通信幀的CAN總線設(shè)備本身作為獲得仲裁優(yōu)先級(jí)的評(píng)判依據(jù)(CAN節(jié)點(diǎn)不參與仲裁),而是以CAN通信幀的ID標(biāo)識(shí)符作為獲得仲裁的依據(jù)(值越小,優(yōu)先級(jí)越高)。類似的概念還存在于以太網(wǎng)應(yīng)用中IP主機(jī)和端口號(hào)的關(guān)系,應(yīng)用程序最終是在端口的層面上進(jìn)行通信,而不僅僅是擁有IP地址的主機(jī)。所以,當(dāng)某一個(gè)CAN節(jié)點(diǎn)設(shè)備可以收納多個(gè)ID的CAN通信幀時(shí),意味著這個(gè)節(jié)點(diǎn)設(shè)備在CAN總線通信系統(tǒng)中可以被抽象成多個(gè)節(jié)點(diǎn)。但實(shí)際上,在后續(xù)介紹的CAN總線通信協(xié)議中可以看到,不同的ID將對(duì)應(yīng)總線系統(tǒng)中不同的服務(wù),總線系統(tǒng)中總有一個(gè)響應(yīng)服務(wù)的線程,可能位于某個(gè)節(jié)點(diǎn)設(shè)備的某一個(gè)ID過濾器之后被實(shí)現(xiàn)。
總線接口單元 - 寄存器清單
FlexCAN外設(shè)模塊的總線接口單元以存儲(chǔ)空間中的寄存器作為操作界面,可由CPU通過外設(shè)總線訪問到FlexCAN外設(shè)模塊內(nèi)部。雖然不建議開發(fā)者通過直接讀寫外設(shè)模塊寄存器的方式對(duì)FlexCAN外設(shè)模塊進(jìn)行開發(fā),因?yàn)橹苯硬僮骷拇嫫鲗?shí)在是一件繁瑣并且容易出錯(cuò)的過程,但本文在這里仍然將FlexCAN外設(shè)模塊的寄存器清單列寫出來,讓讀者一覽FlexCAN外設(shè)模塊為軟件系統(tǒng)開放的應(yīng)用接口。FlexCAN外設(shè)模塊的寄存器如表x所示。
表x FlexCAN外設(shè)模塊寄存器清單
數(shù)據(jù)結(jié)構(gòu) - 消息緩沖區(qū)MB
FlexCAN外設(shè)地址空間的0x0080 - 0x017F之間的地址,被映射到RAM中,用于存放MB的數(shù)據(jù)結(jié)構(gòu),每個(gè)MB占用連續(xù)的16個(gè)字節(jié),總共16個(gè)MB。這些MB將用于存放即將向CAN總線發(fā)送的幀數(shù)據(jù)內(nèi)容,軟件需要先把數(shù)據(jù)填充到MB中再啟動(dòng)發(fā)送工程;或者從CAN總線上捕獲的CAN數(shù)據(jù)內(nèi)容,之后軟件就可以從MB中讀到接收幀的信息。MB在存儲(chǔ)空間中的數(shù)據(jù)結(jié)構(gòu),如圖x所示。
figure-flexcan-mb-struct
圖x MB消息緩沖區(qū)結(jié)構(gòu)其中各字段功能為:
- CODE (Message Buffer Code):CPU和FlexCAN外設(shè)都可能向這個(gè)字段寫命令。當(dāng)CPU向CODE字段中寫數(shù),用于向FlexCAN外設(shè)配置發(fā)送和接收的過程;當(dāng)FlexCAN外設(shè)向CODE字段中寫數(shù),用于告知CPU當(dāng)前發(fā)送或接收過程已經(jīng)完成或者正在進(jìn)行的狀態(tài)。關(guān)于具體的各種命令以及對(duì)應(yīng)的操作和狀態(tài),可進(jìn)一步參見芯片手冊(cè)中的表格說明(Table 50-5 & Table 50-6)。
- SRR (Substitute Remote Request),僅用于擴(kuò)展幀。當(dāng)表示擴(kuò)展幀時(shí),必須置1。
- IDE (ID Extended Bit):標(biāo)記是否為擴(kuò)展幀,1表示擴(kuò)展幀,0表示標(biāo)準(zhǔn)幀。
- RTR (Remote Transmission Request):設(shè)定或表示當(dāng)前MB中是否為遠(yuǎn)程請(qǐng)求幀,1表示遠(yuǎn)程幀,0表示數(shù)據(jù)幀。
- DLC (Length of Data in Bytes):發(fā)送和接收幀中的數(shù)據(jù)長(zhǎng)度,0表示沒有。有效值為1到8。當(dāng)接收通信幀時(shí),F(xiàn)lexCAN協(xié)議引擎會(huì)從接收到的幀中提取有效數(shù)據(jù)填充到數(shù)據(jù)字段,并復(fù)制接收幀的DLC值到MB的DLC字段中。當(dāng)發(fā)送通信幀時(shí),在總線上發(fā)送通信幀的字節(jié)流時(shí),若DLC小于8,則實(shí)際數(shù)據(jù)負(fù)載的字節(jié)流長(zhǎng)度亦會(huì)對(duì)應(yīng)縮短,而不會(huì)填充空位。當(dāng)RTR=1,即發(fā)送遠(yuǎn)程幀時(shí),此時(shí)發(fā)送數(shù)據(jù)字段中無有效內(nèi)容,將會(huì)忽略DLC中的值(等價(jià)于DLC=0)。
- TIMESTAMP (Free-Running Counter Time Stamp):接收幀時(shí)本機(jī)填入時(shí)間戳,用于本機(jī)處理多個(gè)MB中的接收幀時(shí)判斷先后時(shí)序。這個(gè)字段將由FlexCAN的協(xié)議引擎自動(dòng)填充,從CAN_TIMER寄存器中復(fù)制過來。
- PRIO (Local Priority):對(duì)本機(jī)多個(gè)MB的發(fā)送幀執(zhí)行仲裁(而不是總線上的設(shè)備,CAN總線對(duì)設(shè)備沒有優(yōu)先級(jí)的概念),使用唯一的發(fā)送引擎按優(yōu)先級(jí)逐個(gè)發(fā)送。這個(gè)字段的值不會(huì)被發(fā)送到CAN總線上,可以被附加到常規(guī)的ID后面,作為一個(gè)配置項(xiàng),當(dāng)CAN_MCR[LPRIO_EN]=1時(shí)生效,僅作用于發(fā)送過程中的多個(gè)MB之前進(jìn)行排序。
- ID (Frame Identifier):在標(biāo)準(zhǔn)幀的格式中,只用到收發(fā)通信幀的高11位(28b - 18b),后續(xù)的低18位被忽略。當(dāng)使用擴(kuò)展幀時(shí),整個(gè)29位的字段全部用于表示通信幀的ID。話說,標(biāo)準(zhǔn)幀和擴(kuò)展幀的區(qū)別就在于ID字段的位數(shù),擴(kuò)展幀使用更多位的ID,可以在總線系統(tǒng)中表示更多的通信幀類型。
- DATA Byte 0-7(Data Field):通信幀的有效數(shù)據(jù)負(fù)載。最多8字節(jié),同DLC字段描述的數(shù)據(jù)字節(jié)數(shù)對(duì)應(yīng)。當(dāng)為發(fā)送幀時(shí),由CPU寫入數(shù)據(jù)到本字段,供FlexCAN引擎發(fā)送到總線上;當(dāng)為接收幀時(shí),F(xiàn)lexCAN的協(xié)議引擎會(huì)在總線上捕獲到數(shù)據(jù)幀后,自動(dòng)復(fù)制值到本字段,供CPU讀取。
CAN總線標(biāo)準(zhǔn)幀同MB消息緩沖區(qū)的有一一對(duì)映關(guān)系,如圖x所示。
figure-flexcan-mb-frame
圖x CAN總線標(biāo)準(zhǔn)幀同MB消息緩沖區(qū)的一一對(duì)映CAN總線擴(kuò)展幀相對(duì)于標(biāo)準(zhǔn)幀,多了SRR的字段,但仍同MB消息緩沖區(qū)有一一對(duì)映的關(guān)系,如圖x所示。
figure-flexcan-mb-frame-ext
圖x CAN總線擴(kuò)展幀同MB消息緩沖區(qū)的一一對(duì)映### 初始化過程
FlexCAN外設(shè)的工作周期從復(fù)位狀態(tài)開始,可以由如下兩種情況觸發(fā)復(fù)位過程:
- 芯片硬件復(fù)位,此時(shí)包括FlexCAN外設(shè)模塊在內(nèi)的所有寄存器都將被復(fù)位
- 配置CAN_MCR[SOFTRST]寄存器位,這會(huì)復(fù)位FlexCAN中的部分配置寄存器。當(dāng)軟件向CAN_MCR[SOFTRST]寄存器位寫1時(shí),向FlexCAN外設(shè)模塊發(fā)出復(fù)位請(qǐng)求,當(dāng)FlexCAN外設(shè)模塊執(zhí)行復(fù)位操作后,會(huì)將這一寄存器位清零,因此軟件可通過輪詢這個(gè)標(biāo)志位在置1后是否清零,判定內(nèi)部軟復(fù)位是否完成。
之后,對(duì)FlexCAN模塊進(jìn)行配置。但要注意,任何對(duì)FlexCAN外設(shè)的配置操作,都需要在FlexCAN外設(shè)的凍結(jié)模式下才能完成。
一般的初始化FlexCAN外設(shè)模塊的過程如下:
- 寫CAN_MCR寄存器,配置FlexCAN引擎的工作模式。
- 寫CAN_CTRL1和CAN_CBT寄存器,配置FlexCAN的CAN時(shí)鐘位時(shí)間。
- 初始化MB列表。MB映射的內(nèi)存區(qū)是帶ECC的,需要先寫入初值才能正常使用。如果啟用了Rx FIFO模式,還必須配置好ID過濾器表。
- 寫CAN_RXIMRn寄存器。
- 寫CAN_IMASK寄存器,啟用必要的中斷。
- 將CAN_MCR[HALT]寄存器清零,退出凍結(jié)模式。
退出凍結(jié)模式之后,F(xiàn)lexCAN外設(shè)模塊開始同CAN總線同步,接入總線網(wǎng)絡(luò)。
接收過程Rx、Rx FIFO及幀過濾機(jī)制Filter
相對(duì)于默認(rèn)的將每個(gè)MB作為一個(gè)單獨(dú)的通道,一幀一幀地接收并處理數(shù)據(jù),F(xiàn)IFO模式可以將幾個(gè)MB的存儲(chǔ)空間組織成一個(gè)FIFO,F(xiàn)IFO可以緩存更多的幀,在CPU提供同等算力的情況下,提升節(jié)點(diǎn)設(shè)備的處理CAN總線通信幀的動(dòng)態(tài)吞吐率。
數(shù)據(jù)結(jié)構(gòu)
當(dāng)配置CAN_MCR[RFEN]=1時(shí),啟用Rx FIFO模式,此時(shí),原MB列表的部分MB存儲(chǔ)區(qū)域(MB0 - MB5,模塊內(nèi)偏移地址為0x80 - 0xDC的內(nèi)存區(qū)域)將合并成Rx FIFO,由FIFO引擎管理。其中,原MB0的作為CPU訪問Rx FIFO的接口,CPU始終可以從原MB0的位置讀到最早進(jìn)入FIFO的幀信息。此時(shí),Rx FIFO的區(qū)域?yàn)橹蛔x模式,復(fù)位缺省值為0x00。
另外,還可以通過配置CAN_CTRL2[RFEN]=1,啟用Rx FIFO的另一段區(qū)域,這個(gè)FIFO對(duì)應(yīng)于原MB6 - MB15的區(qū)域(模塊內(nèi)偏移地址為0xE0 - 0x17C的內(nèi)存區(qū)域,將用于存放Rx FIFO的ID過濾器表,只有通過ID過濾器表中的表項(xiàng)匹配的CAN通信幀才能被捕獲進(jìn)入Rx FIFO。ID過濾器表可能有多種模式(匹配不同的位數(shù)),可被配置為8至40個(gè)表項(xiàng)。復(fù)位FlexCAN外設(shè)模塊后,ID過濾器表的內(nèi)存區(qū)域的默認(rèn)為從0xE0至0xFC,對(duì)應(yīng)使用原MB6和MB7的空間,同未開啟Rx FIFO模式的配置兼容。圖x展示了Rx FIFO的數(shù)據(jù)結(jié)構(gòu)。
figure-flexcan-rx-fifo-struct
圖x FlexCAN Rx FIFO數(shù)據(jù)結(jié)構(gòu)其中,每個(gè)ID過濾器表項(xiàng)(ID Filter Table element)占用32位字的空間,可以被分成1個(gè)32位、2個(gè)16位或4個(gè)8位的匹配接收掩碼(IDAF,Identifier Acceptance Filters),這需要在CAN_MCR[IDAM]寄存器中設(shè)置。圖x中展示了這種可能使用多種格式分割I(lǐng)D過濾器表項(xiàng)的格式,但要特別注意,一旦選定一種格式,所有的ID過濾器表項(xiàng)都會(huì)使用同一種格式。
figure-flexcan-id-filter-table
圖x FlexCAN ID過濾器表項(xiàng)的格式其中,各配置字段的含義如下:
- RTR (Remote Frame):指定能否捕獲匹配ID的遠(yuǎn)程幀。1指定可以捕獲,0指定不捕獲。
- IDE (Extended Frame):指定能否捕獲匹配ID的擴(kuò)展幀。1指定可以捕獲,0指定不捕獲擴(kuò)展幀,僅捕獲標(biāo)準(zhǔn)幀。
- RXIDA/B/C (Rx Frame Identifier with Format A/B/C):指定匹配的ID模式,當(dāng)不滿足完整的幀ID時(shí),僅匹配幀的高位。
FIFO中MB結(jié)構(gòu)中多出來的IDHIT (Identifier Acceptance Filter Hit Indicator):表示當(dāng)前的MB匹配到了哪個(gè)ID過濾器。
功能描述
Rx FIFO將6個(gè)MB的內(nèi)存空間整合成一個(gè)FIFO,使用FIFO引擎管理先后收到的數(shù)據(jù)幀。相對(duì)于老式的單獨(dú)管理各個(gè)MB,F(xiàn)IFO模式對(duì)DMA應(yīng)用比較友好,并且可以提升從CAN總線上捕獲幀的動(dòng)態(tài)吞吐率。
CAN_IFLAG1[BUF5I]標(biāo)志位,表示Rx FIFO中已經(jīng)捕獲到有效的數(shù)據(jù)幀,可供CPU讀取。這個(gè)標(biāo)志位也可以觸發(fā)中斷,CPU在中斷服務(wù)程序中讀取Rx FIFO的內(nèi)容后,F(xiàn)lexCAN外設(shè)會(huì)更新FIFO狀態(tài)寄存器CAN_RXFIR的值,然后自動(dòng)清中斷標(biāo)志。如果Rx FIFO中有多個(gè)有效的數(shù)據(jù)幀,則CAN_IFLAG1[BUF5I]會(huì)持續(xù)置位,觸發(fā)CPU處理接收幀的過程,直到Rx FIFO中捕獲的通信幀全部被讀走。
CAN_IFLAG1[BUF6I]標(biāo)志位,表示Rx FIFO達(dá)到警告門限,此時(shí)Rx FIFO中已經(jīng)積壓了4個(gè)MB(從5個(gè)MB讀走1個(gè)后剩下4個(gè)MB的時(shí)機(jī)),此時(shí)意味著Rx FIFO幾乎要滿到溢出了。這個(gè)標(biāo)志位需要CPU清除。
CAN_IFLAG1[BUF7I]標(biāo)志位,表示Rx FIFO已經(jīng)滿溢,此時(shí)Rx FIFO中已經(jīng)積壓了6個(gè)未讀的MB,并且有一個(gè)新的CAN通信幀被捕獲下來。這個(gè)標(biāo)志位需要CPU清除。
CAN_IFLAG1[BUF0I]標(biāo)志位,可用于清空Rx FIFO。當(dāng)CPU向該標(biāo)志位寫1時(shí),直接清空Rx FIFO。但這個(gè)功能僅在凍結(jié)模式下使用,這就意味著,用戶不要試圖在FlexCAN正常工作的情況下清空Rx FIFO(可以軟件讀掉Rx FIFO中的數(shù)據(jù)),這個(gè)功能大多用于改變?nèi)峙渲脮r(shí),重新初始化FlexCAN模塊時(shí)使用。
FlexCAN模塊中設(shè)計(jì)了功能強(qiáng)大(略顯復(fù)雜)的幀過濾器模式,可以由硬件自動(dòng)過濾掉很多本設(shè)備處理不了的幀,這就節(jié)約了很多原本需要在接收中斷服務(wù)程序中判斷捕獲幀是否能在本機(jī)處理的過程。FlexCAN可以同時(shí)匹配眾多的ID幀標(biāo)識(shí)符,128個(gè)Format A格式的IDAF,或者256個(gè)Format B格式的IDAF,或者512個(gè)Format C格式的IDAF。每個(gè)捕獲到Rx FIFO中的接收幀都有一個(gè)對(duì)應(yīng)的IDHIT,指示它匹配到的過濾器的索引編號(hào),CAN_RXFIR[IDHIT]寄存器字段中也能查看最近捕獲的接收幀的IDHIT值。此時(shí),需要在清接收標(biāo)志之前讀CAN_RXFIR寄存器,以確保存放在CAN_RXFIR寄存器中的值不會(huì)被后面捕獲到幀覆蓋掉。
當(dāng)配置CAN_CTRL2[RFEN]=1時(shí),啟用過濾器表,過濾器表中最多可以有16個(gè)表項(xiàng),可以由獨(dú)立掩碼寄存器CAN_RXIMRx分別配置。當(dāng)CAN_MCR[IRMQ]=0時(shí),過濾器表由CAN_RXFGMASK寄存器配置。
接收過程
為了能讓FlexCAN從CAN總線上捕獲到通信幀,CPU(軟件)需要準(zhǔn)備一些工作:
- 如果選定的MB處于激活狀態(tài),正在發(fā)送或接收,要么等等,要么強(qiáng)行終止,確保MB處于一個(gè)可用的非激活狀態(tài)
- 向MB中寫入希望捕獲通信幀的ID值。
- 向MB的CODE字段中寫入EMPTY(0b0100),激活接收過程。
當(dāng)MB被激活后,它將會(huì)接收到通過ID過濾器匹配的通信幀。
當(dāng)接收過程成功完成后,F(xiàn)lexCAN外設(shè)通過搬運(yùn)過程將捕獲到的通信幀從CAN通信引擎的緩沖中轉(zhuǎn)運(yùn)至MB中:
- 接收到通信幀的數(shù)據(jù)(8字節(jié))將被存放至MB的DATA字段。
- 接收到的ID將被存放至MB的ID字段。
- 接收時(shí)刻的定時(shí)器CAN_TIMER寄存器的值將被寫入到MB的時(shí)間戳字段中。
- MB中的SRR、IDE、RTR和DLC字段將被更新。
- MB中的CODE字段中的狀態(tài)將被更新。
- CAN_IFLAG1中的接收中斷標(biāo)志位將會(huì)置位,如果在CAN_IMASK1寄存器中啟用了對(duì)應(yīng)的中斷,也將會(huì)觸發(fā)中斷。
因此,建議CPU(軟件)在讀取CAN接收幀時(shí),遵循如下步驟:
- 先讀一下對(duì)應(yīng)MB的狀態(tài)位,再看一下BUSY標(biāo)志位是否置位,若置位,意味著MB被鎖著,先等一等。
- 從MB中讀數(shù)據(jù)。但如果MB被鎖著,MB中的數(shù)據(jù)實(shí)際是無效的。
- 清IFLAG標(biāo)志位。
- 讀時(shí)間戳。
建議當(dāng)收到CAN接收幀時(shí),盡快把收到的幀讀走,解鎖MB,為后面接收的幀釋放空間。
特別注意的是,在CPU通過輪詢過程查看FlexCAN‘釋放捕獲到接收幀的過程中,應(yīng)當(dāng)以CAN_IFLAG1寄存器中的標(biāo)志位來判定,而不是MB中CODE字段的狀態(tài)碼。讀CODE狀態(tài)碼是沒有意義的,因?yàn)橐坏〧lexCAN收到通信幀后被CPU讀走,CODE不會(huì)變?yōu)镋MPTY,而是仍保持為FULL,需要CPU人為清空。
若是使用FIFO模式,CPU需要在FlexCAN的凍結(jié)模式下配置啟用Rx FIFO模式,再次啟用FlexCAN通信引擎后,F(xiàn)lexCAN將以Rx FIFO模式捕獲CAN通信幀:
- 讀CAN_IFLAG中的Rx FIFO的接收標(biāo)志位
- 讀Rx FIFO頭部MB的接收幀ID
- 讀Rx FIFO頭部MB的數(shù)據(jù)負(fù)載(8字節(jié))
- 讀CAN_RXFIR寄存器
- 寫1清Rx FIFO捕獲到有效幀的標(biāo)志位CAN_IFLAG[BUF5I]。
Rx FIFO對(duì)使用DMA的場(chǎng)景更友好。但目前的ECU系統(tǒng)中,因?yàn)楦郊恿藚f(xié)議棧和大量的軟件干預(yù),所以實(shí)際使用DMA的并不多。如果需要,也可以參見芯片用戶手冊(cè)的相關(guān)說明。
發(fā)送過程Tx和仲裁機(jī)制winner
發(fā)送過程
當(dāng)要發(fā)送一個(gè)CAN通信幀,CPU需要選出一個(gè)MB,然后執(zhí)行如下的步驟:
- 查看當(dāng)前CAN通信引擎是否正忙,如果正忙就等一等,或者通過硬件機(jī)制終止通信過程。是否有之前通信過程的遺留標(biāo)志位,如果有就清零。務(wù)必確保CAN通信引擎恢復(fù)成初始狀態(tài):
- 確保發(fā)送中斷和接收中斷都是停用的。
- 如果選用的MB是激活的(Active),正在被占用,可以通過向該MB的CODE字段中寫入ABORT命令字(0b1001)終止通信過程。
- 通過輪詢CAN_IFLAG寄存器中對(duì)應(yīng)的IFLAG標(biāo)志位置位,或者啟用中斷觸發(fā),等待MB轉(zhuǎn)入非激活狀態(tài)。
- 再讀MB的CODE字段,確認(rèn)發(fā)送過程已經(jīng)被中斷或者完成。
- 清除對(duì)應(yīng)的中斷標(biāo)志位。
- 向MB中寫入通信幀:
- 寫入消息ID。如果通過配置CAN_MCR[LPRIO_EN]=1寄存器啟用了本地優(yōu)先級(jí)配置,還需要一并寫入PRIO配置字段。
- 寫入數(shù)據(jù)負(fù)載。最多8個(gè)字節(jié)的數(shù)據(jù)。
- 配置發(fā)送屬性,包括:IDE、RTR、DLC。
- 在CODE字段中寫入激活命令碼,對(duì)應(yīng)發(fā)送幀,CODE=0xC。
當(dāng)MB被激活之后,它被加入到FlexCAN外設(shè)的發(fā)送仲裁過程,根據(jù)本地優(yōu)先級(jí)(若有),最終被發(fā)送到CAN總線上。
在發(fā)送過程成功完成后:
- 定時(shí)器CAN_TIMER寄存器的時(shí)間戳將被寫入到本MB的時(shí)間戳字段中。
- CODE字段中的值將被FlexCAN外設(shè)更新。至于更新成什么狀態(tài),需要根據(jù)具體發(fā)送的情況確定。見表x所示。
- 在CAN_IFLAG1寄存器中的發(fā)送完成中斷標(biāo)志位會(huì)置位,
- 如果在CAN_IMASK1寄存器中啟用了發(fā)送完成中斷,那么對(duì)應(yīng)的中斷也會(huì)被觸發(fā)。
注意,當(dāng)通過CAN_MCR[AEN]啟用了終止通信的功能后,當(dāng)發(fā)送完整中斷標(biāo)志位置位時(shí),此時(shí)MB是被鎖住的,需要CPU清中斷標(biāo)志位后,才能再次訪問MB,準(zhǔn)備寫入下一個(gè)新的通信幀。
仲裁過程
此處的仲裁過程并不是指CAN總線網(wǎng)絡(luò)的仲裁機(jī)制,而是FlexCAN外設(shè)本身的多個(gè)通信通道(MB)爭(zhēng)用同一個(gè)通信引擎發(fā)送至CAN總線上的過程。FlexCAN會(huì)掃描當(dāng)前所有待發(fā)送的MB,然后根據(jù)特定的策略選出其中一個(gè)作為本次發(fā)送過程的MB。這個(gè)策略是可以通過寄存器配置的,如表x所示。
表x 配置發(fā)送仲裁優(yōu)先級(jí)策略
關(guān)于仲裁的過程,還有更多的細(xì)節(jié),例如,當(dāng)某個(gè)MB被激活發(fā)送過程后,如果長(zhǎng)時(shí)間得不到仲裁優(yōu)先級(jí),也將會(huì)產(chǎn)生一些報(bào)警,此時(shí),判斷超時(shí)和報(bào)警的機(jī)制,在FlexCAN外設(shè)模塊上有一些具體的實(shí)現(xiàn)策略。這些內(nèi)容可以根據(jù)具體問題具體分析,在遇到具體場(chǎng)景時(shí),再查閱手冊(cè)一一對(duì)癥。此處就不做贅述了。
總結(jié)
本文描述了一個(gè)典型的CAN總線通信引擎FlexCAN外設(shè)模塊的工作機(jī)制。FlexCAN總線以消息緩沖區(qū)MB作為數(shù)據(jù)緩沖單元,收發(fā)通信過程同典型的基本通信類引擎(例如UART)相似,但由于CAN總線以通信幀作為基本通信單元(包含ID和最多8個(gè)字節(jié)的數(shù)據(jù)負(fù)載),而不是基本通信引擎的單元數(shù)據(jù),所以需要一個(gè)協(xié)議引擎,同步地在總線和MB之間搬運(yùn)包含數(shù)據(jù)和狀態(tài)的幀屬性信息。CAN總線是一個(gè)多對(duì)多的網(wǎng)絡(luò),因此也引入了網(wǎng)絡(luò)型通信引擎的問題,例如接收過程的目標(biāo)地址(ID)匹配,和發(fā)送過程中的仲裁(沖突檢測(cè))。FlexCAN外設(shè)模塊在硬件上也提供了對(duì)這些問題的解決方案,在接收過程中,設(shè)計(jì)了非常靈活的接收標(biāo)識(shí)符過濾器組的機(jī)制;在發(fā)送過程中,設(shè)計(jì)了(在本地多個(gè)待發(fā)送MB之間的)本地優(yōu)先級(jí)的機(jī)制,至于CAN總線網(wǎng)絡(luò)上的仲裁,就依賴于網(wǎng)絡(luò)本身的物理特性完成了。FlexCAN外設(shè)還增加實(shí)現(xiàn)了Rx FIFO的工作模式,可以將多個(gè)MB合在一起以FIFO的方式進(jìn)行管理,使用FIFO可以提升FlexCAN外設(shè)在總線上的動(dòng)態(tài)吞吐率,并且對(duì)DMA操作更加友好。本文對(duì)于FlexCAN內(nèi)部機(jī)制的一些實(shí)現(xiàn)細(xì)節(jié)僅點(diǎn)到為止,未做詳細(xì)的拆解,如果讀者在具體應(yīng)用中遇到具體問題,仍可參見芯片用戶手冊(cè)進(jìn)行針對(duì)性閱讀。
-
微控制器
+關(guān)注
關(guān)注
48文章
7570瀏覽量
151623 -
CAN總線
+關(guān)注
關(guān)注
145文章
1952瀏覽量
130867 -
接口
+關(guān)注
關(guān)注
33文章
8645瀏覽量
151398 -
總線通信
+關(guān)注
關(guān)注
0文章
51瀏覽量
11834 -
MM32F5
+關(guān)注
關(guān)注
0文章
12瀏覽量
536
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論