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