摘 要: 針MCP2515芯片的特點,提出了一種新的MCP2515驅動實現方法。把MCP2515的SPI口同MCU的SPI口相連,在EVC下用SPI接口的方式實現MCP2515的驅動。在驅動中,再加上了緩沖管理機制和雙注冊的機制,避免CAN總線上的干擾數據。
關鍵詞: 緩沖 雙注冊 MCP2515 CAN總線 SPI
在WINCE的驅動編寫中,一般都采用標準的編寫方式,即分層式結構[1]。分層式結構驅動程序依賴于一段可在平臺間再使用的代碼,以簡化和縮短開發時間。這段由微軟提供的代碼稱為模塊設備驅動程序MDD,用來實現驅動程序的核心功能。MDD并不直接存取硬件,而是依靠另一段與硬件有關的代碼存取硬件,這段代碼被稱為平臺相關驅動程序PDD。當將一個平臺的分層驅動程序用于另一個平臺時,只要重寫PDD即可,而不必重寫整個驅動程序。MDD和PDD之間有一個設備驅動程序服務提供商的接口DDSPI,該接口定義了一些PDD功能,這些功能在執行期間內被MDD調用。這種方法相對來說要簡單一些,因為有模版可用,但在調試驅動的時很不方便。因為分層結構的驅動和WINCE的內核是密切相關的,在調試驅動程序時,必須先把內核編譯好,然后下載內核到目標平臺上,才能夠調試,因而效率很低。本文采用另一種脫離內核的方式在WINCE中實現MCP2515的驅動程序,即在EVC的平臺下,通過SPI接口來做驅動MCP2515的工作。這樣,編寫的驅動直接編譯成一個動態鏈接庫" title="動態鏈接庫">動態鏈接庫DLL,把這個動態鏈接庫拷貝到目標平臺上,就可以使用。而且,通過這種方式,實現了更加靈活的功能。
1 MCP2515芯片介紹
CAN(Controller Area Network)總線[2],即控制器局域網總線,是一種有效支持分布式控制或實時控制的串行通信網絡。由于其高性能、高可靠性及獨特的設計和適宜的價格而廣泛應用于工業現場控制、智能樓宇、醫療器械、交通工具以及傳感器等領域。CAN是一種基于廣播方式的協議,主從式網絡結構,也是一種串行數據通信協議,一種多主總線,通信介質可采用雙絞線、同軸電纜或光纖。
Microchip公司推出的CAN總線控制器芯片MCP2515符合CAN2.B技術規范并帶有符合工業標準的SPI串行接口,是目前市場上體積最小、最易于使用也是最節約成本的獨立CAN協議控制器芯片[3][4]。MCP2515具備最高40MHz時鐘輸入速度以及一個10MHz高速SPI接口,還可根據前兩個數據字節和11位標識符對報文進行濾波。
MCP2515能夠發送和接收標準數據幀" title="數據幀">數據幀以及擴展數據幀,并具有接收過濾和信息管理的功能。MCP2515通過其SI引腳同MCU進行數據傳輸,最高數據傳輸速率可達1Mbps。MCU可以通過MCP2515與CAN總線上的其他MCU進行通信。MCP2515內含三個14 字節的發送緩沖器,二個14字節的接收緩沖器,并且具有靈活的中斷能力、幀屏蔽和過濾、幀優先級設定等特性。
MCP2515的主要功能參數:(1)支持CAN協議2.0A/2.0B;(2)最大" title="最大">最大可編程波特率為1Mbps;(3)有標準幀和擴展幀兩種數據幀可供選擇,每個幀中的數據段長可為0~8字節;(4)支持遠程幀;(5)內含3個發送緩沖器和2個接收緩沖器,并且其優先級可編程設定;(6)內含6個29字節的接收過濾器和2個29字節的接收過濾屏蔽器;(7)具有(loop-back)自環檢測模式;(8)標準幀數據段的前兩個字節的單獨過濾功能。
圖1為MCP2515的內部結構原理圖,其中CAN模塊包括CAN協議機和發送、接收緩沖器以及他們的屏蔽器、過濾器。CAN協議機主要負責與CAN總線的接口,SPI接口邏輯負責實現與MCU的接口,而緩沖器、過濾器組和控制邏輯以及與之相關的位定時發生器、控制和中斷寄存器則負責實現各種工作模式的設定和操作控制。MCP2515芯片在CAN總線上的數據接收是通過2個接收緩沖器、2個接收屏蔽器、6個接收過濾器的組合來實現的。CAN總線上只有同時滿足至少任意一個接收屏蔽器和一個接收過濾器的條件的幀,才可以進入接收緩沖器。MCU可以通過SPI接口來讀取MCP2515接收緩沖器里的數據。MCP2515對CAN總線的數據發送則沒有限制,只要用MCU通過SPI接口將待發送的數據寫入MCP2515的發送緩沖器,然后再調用RTS(發送請求)命令即可將數據發送到CAN總線上。MCU通過使用標準SPI讀寫命令對MCP2515寄存器進行讀寫操作。
MCP2515具有靈活的中斷管理功能。它有8個中斷源,包括發送、接收中斷、各種錯誤中斷以及總線喚醒中斷等。MCU可以通過對MCP2515的中斷允許控制寄存器CANINTE的設置來設定和屏蔽各種中斷的發生條件,并可以通過讀取MCP2515的中斷標志位寄存器CANINTE或者讀取CANSTAT寄存器中的ICOD部分來判斷當前中斷的中斷源。
2 緩沖管理的驅動實現
2.1 驅動框架和流程
按照WINCE的標準的分層結構來實現MCP2515的驅動,由于分層結構的WINCE驅動程序和操作系統內核是緊密結合在一起的,調試驅動時效率很低,而且這種方式實現的驅動,功能也不夠靈活,所以本文不再采用這種方式,而是直接在EVC下用SPI接口的方式來操作MCP2515芯片。硬件采用三星的ARM內核的S3C2440A,該CPU帶有2通道SPI口,可以直接和MCP2515帶的SPI相連。S3C2440A通過SPI口就可以操作MCP2515芯片,實現CAN協議的數據收發。
在CAN總線中,各種在CAN總線上傳輸的數據幀都被分配一個惟一的標識符,每個節點根據這些標識符來確定是否接收這些幀。當然還必須與過濾器及屏蔽器配合,共同決定是否接收數據" title="接收數據">接收數據。
本文提到的CAN總線分成父設備和子設備,子設備會主動把自己的數據上傳給父設備,父設備收到數據后,對這些數據進行進一步的處理,例如,在屏幕上以圖表的形式顯示出來等。圖2顯示了CAN總線的網絡結構。
?
?
CAN父設備就是一個帶有MCP2515芯片的ARM嵌入式系統。CAN子設備也可以是一個帶MCP2515的嵌入式系統,也可以是其他一些CAN設備。本文中主要介紹MCP2515在CAN父設備上" title="設備上">設備上的驅動程序實現。圖3是驅動程序框圖。
MCP2515主要提供了狀態查詢以及中斷兩種數據操作模式,本文中MCP2515主要采用狀態查詢模式進行CAN總線數據的接收和發送。在系統上電后,先對MCP2515芯片進行初始化的工作,主要是設置MCP2515芯片的相關寄存器的值,如設置波特率,屏蔽寄存器,過濾寄存器等。初始化工作完成后,開啟一個線程負責收發數據。如果發送緩沖中有數據需要發送,則發送數據,否則,查詢MCP2515的CANINTF寄存器的第0和1兩位,如果有數據則接收數據,然后判斷該幀ID是否在父設備上注冊,如果已注冊,則把數據放到接收緩沖區中,否則,就丟掉繼續循環,直到這個線程終止。
2.2 接收緩沖
在驅動中,為了保證接收的數據不會丟失,需要添加一個緩沖,用來緩存接收到的數據。在接收緩沖中,完全以幀的形式存放,方便后續的數據處理。在CAN總線中,主要有以下的幾種幀:
數據幀:數據幀攜帶數據從發送器至接收器。
遠程幀:總線單元發出遠程幀,請求發送具有同一識別符的數據幀。
錯誤幀:任何單元檢測到總線錯誤就發出錯誤幀。
過載幀:過載幀用以在先行的和后續的數據幀(或遠程幀)之間提供附加的延時。
當然,驅動程序并不緩存所有的幀,只緩存需要的數據幀和遠程幀,以下是驅動中定義幀結構的數據成員:
DWORD dwID;
BOOL bRemoteFlag;
BOOL bExternFlag;
BYTE DLCLen;
BYTE Data[9];
結構名稱為CAN_RECV_FRAME,dwID為幀ID,bRemoteFlag是遠程幀標志,bExternFlag 為擴展幀標志,DLCLen是數據長度,它可以是0~8中的任何數值,Data[9]是幀數據的緩沖區,最多使用其中8個字節。然后定義CList類型的成員變量m_RevList作為一個接收的隊列:
CList
在對緩沖區初始化時,一次就分配了足夠的數據空間,而不必在使用時再動態申請內存,這樣保證了系統占用的內存資源的確定性。線程在存取緩沖區時必須要事先鎖定,保證在一個時刻只有一個線程對緩沖區進行存取操作。為了提高對資源的利用率,驅動中把緩沖變成一個循環隊列,再定義了一個RECV_FRAME_USE的結構來管理緩沖區,該結構的數據成員如下:
POSITION pHead;
POSITION pTail;
Int iLen;
pHead是頭指針,pTail是尾指針,iLen為隊列使用長度。有了RECV_FRAME_USE這個結構后,緩沖區就成了一個幀的循環隊列。在系統收到幀時,就把該幀放到隊列的后面。如果數據緩沖區已滿,則清空頭一幀,實現先進先出。在沒有加上過濾以前,收到的總線上的所有的數據幀都放在緩沖中。
2.3 發送緩沖
發送緩沖區和接收緩沖區不同,接收緩沖區之所以這樣設計,是因為在MCP2515收到數據后,要進行解幀,把幀ID、幀的類型、數據長度和數據這些信息分開,分別存放在幀結構的對應變量中,這樣可方便后續的處理。但是在發送時必須先進行組幀,而且要讓MCP2515把數據發送出去,必須把幀的數據(如幀ID、何種幀、數據的長度以及數據等)按MCP2515的要求,送到MCP2515相應寄存器中的對應位。所以,在組織發送數據時,必須把要發送的數據按照MCP2515的寄存器要求進行組織,這樣在發送時,直接把組織好的數據逐字節送到對應的MCP2515的寄存器即可。MCP2515有三個14字節SRAM發送緩沖,并映射到存儲器中。其中第一字節TXBNCTRL 是與報文緩沖器相關的控制寄存器。該寄存器中的信息決定了報文在何種條件下被發送,并在報文發送時指示其狀態。用5個字節來裝載標準和擴展標識符以及其他報文仲裁信息。最后8個字節用來裝載等待發送的報文的8個可能的數據字節。所以,在發送緩沖區中,只保存5個字節的標準和擴展標識符以及其他報文仲裁信息,8個字節用來保存發送的數據。在驅動中,定義了一個名為MCP2515_SEND_BUFFER的發送緩沖區,以下是該緩沖區的數據成員。
DWORD dwWritePointer;
DWORD dwReadPointer;
BYTE Data[MAX_SEND_LEN]
該緩沖區也是一個循環緩沖,dwWritePointer為發送緩沖的寫指針,dwReadPointer為發送緩沖的讀指針,Data就是存放幀數據的隊列,MAX_SEND_LEN為隊列的最大長度。該隊列的數據格式是:長度+5個字節標示符+數據。因為數據的長度最大為8個字節,得出長度最大就是13個字節。所以,長度用BYTE型就可以表示了,這樣pData存放的數據就很規整。在發送時,從pData中取走一幀后,直接把前5個字節標準和擴展標識符以及其他報文仲裁信息和后面數據字節送到MCP2515對應對寄存器即可,不用解幀和組幀過程,從而加快發送進程。
2.4 雙注冊機制
MCP2515芯片具有兩個驗收屏蔽寄存器(分別對應不同的接收緩沖器)以及六個驗收過濾寄存器,它們共同來決定報文是否應被載入接收緩沖器。 一旦報文集成緩沖器(MBA)接收到有效報文,報文中的標識符字段將與過濾寄存器中的值進行比較。如果兩者匹配,該報文將被載入相應的接收緩沖器。濾波屏蔽寄存器用來確定濾波器對標識符中的哪些位進行校驗,這樣可以直接屏蔽一些不希望收到的數據。這一機制對于所有的有MCP2515芯片的設備都是有用的。在利用緩沖區來緩存收到的數據后,畢竟驅動程序中的緩沖區大小受限,有時并不需要把所有收到的數據放在緩沖中,所以對進入緩沖區的數據再加上一次過濾,即在父設備上注冊的機制。只有在父設備上注冊了ID的子設備,父設備才會把數據放到數據緩沖區中。在父設備的驅動中,有一個列表專門用來保存子設備注冊的ID,每次父設備收到數據在放到緩沖區中以前,都會比較一下,在列表中有沒有這個ID,如有就放到緩沖區中,如沒有則丟掉。這樣又可以屏蔽掉總線上的一些無關的數據,從而提高了效率。
本文詳細介紹了MCP2515在WINCE中的實現過程和主要技術,但是限于篇幅,沒能給出詳細的軟件源程序。實踐證明,該驅動在CAN總線實際的應用中效果明顯,既提高了開發的效率,又實現了更靈活的功能。
參考文獻
1 Boling D.Microsoft Windows CE程序設計.北京:北京大學出版社,1998
2 饒運濤.現場總線CAN原理與應用技術.北京:北京航空航天大學出版社,2003
3 Microchip公司.MCP2515,Stand-Alone CAN Controller With SPITM Interface.2003
4 Microchip公司.AN215,A Simple CAN Node Using the MCP2510 and PIC12C67X.2002