《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 通信與網(wǎng)絡(luò) > 業(yè)界動(dòng)態(tài) > 基于緩沖管理的MCP2515驅(qū)動(dòng)實(shí)現(xiàn)

基于緩沖管理的MCP2515驅(qū)動(dòng)實(shí)現(xiàn)

《電子技術(shù)應(yīng)用》
2008-03-21
作者:劉光倫,廖建明

  摘 要: 針MCP2515芯片的特點(diǎn),提出了一種新的MCP2515驅(qū)動(dòng)實(shí)現(xiàn)方法。把MCP2515的SPI口同MCU的SPI口相連,在EVC下用SPI接口的方式實(shí)現(xiàn)MCP2515的驅(qū)動(dòng)。在驅(qū)動(dòng)中,再加上了緩沖管理機(jī)制和雙注冊(cè)的機(jī)制,避免CAN總線上的干擾數(shù)據(jù)。
  關(guān)鍵詞: 緩沖 雙注冊(cè) MCP2515 CAN總線 SPI


  在WINCE的驅(qū)動(dòng)編寫(xiě)中,一般都采用標(biāo)準(zhǔn)的編寫(xiě)方式,即分層式結(jié)構(gòu)[1]。分層式結(jié)構(gòu)驅(qū)動(dòng)程序依賴于一段可在平臺(tái)間再使用的代碼,以簡(jiǎn)化和縮短開(kāi)發(fā)時(shí)間。這段由微軟提供的代碼稱為模塊設(shè)備驅(qū)動(dòng)程序MDD,用來(lái)實(shí)現(xiàn)驅(qū)動(dòng)程序的核心功能。MDD并不直接存取硬件,而是依靠另一段與硬件有關(guān)的代碼存取硬件,這段代碼被稱為平臺(tái)相關(guān)驅(qū)動(dòng)程序PDD。當(dāng)將一個(gè)平臺(tái)的分層驅(qū)動(dòng)程序用于另一個(gè)平臺(tái)時(shí),只要重寫(xiě)PDD即可,而不必重寫(xiě)整個(gè)驅(qū)動(dòng)程序。MDD和PDD之間有一個(gè)設(shè)備驅(qū)動(dòng)程序服務(wù)提供商的接口DDSPI,該接口定義了一些PDD功能,這些功能在執(zhí)行期間內(nèi)被MDD調(diào)用。這種方法相對(duì)來(lái)說(shuō)要簡(jiǎn)單一些,因?yàn)橛心0婵捎?,但在調(diào)試驅(qū)動(dòng)的時(shí)很不方便。因?yàn)榉謱咏Y(jié)構(gòu)的驅(qū)動(dòng)和WINCE的內(nèi)核是密切相關(guān)的,在調(diào)試驅(qū)動(dòng)程序時(shí),必須先把內(nèi)核編譯好,然后下載內(nèi)核到目標(biāo)平臺(tái)上,才能夠調(diào)試,因而效率很低。本文采用另一種脫離內(nèi)核的方式在WINCE中實(shí)現(xiàn)MCP2515的驅(qū)動(dòng)程序,即在EVC的平臺(tái)下,通過(guò)SPI接口來(lái)做驅(qū)動(dòng)MCP2515的工作。這樣,編寫(xiě)的驅(qū)動(dòng)直接編譯成一個(gè)動(dòng)態(tài)鏈接庫(kù)" title="動(dòng)態(tài)鏈接庫(kù)">動(dòng)態(tài)鏈接庫(kù)DLL,把這個(gè)動(dòng)態(tài)鏈接庫(kù)拷貝到目標(biāo)平臺(tái)上,就可以使用。而且,通過(guò)這種方式,實(shí)現(xiàn)了更加靈活的功能。
1 MCP2515芯片介紹
  CAN(Controller Area Network)總線[2],即控制器局域網(wǎng)總線,是一種有效支持分布式控制或?qū)崟r(shí)控制的串行通信網(wǎng)絡(luò)。由于其高性能、高可靠性及獨(dú)特的設(shè)計(jì)和適宜的價(jià)格而廣泛應(yīng)用于工業(yè)現(xiàn)場(chǎng)控制、智能樓宇、醫(yī)療器械、交通工具以及傳感器等領(lǐng)域。CAN是一種基于廣播方式的協(xié)議,主從式網(wǎng)絡(luò)結(jié)構(gòu),也是一種串行數(shù)據(jù)通信協(xié)議,一種多主總線,通信介質(zhì)可采用雙絞線、同軸電纜或光纖。
  Microchip公司推出的CAN總線控制器芯片MCP2515符合CAN2.B技術(shù)規(guī)范并帶有符合工業(yè)標(biāo)準(zhǔn)的SPI串行接口,是目前市場(chǎng)上體積最小、最易于使用也是最節(jié)約成本的獨(dú)立CAN協(xié)議控制器芯片[3][4]。MCP2515具備最高40MHz時(shí)鐘輸入速度以及一個(gè)10MHz高速SPI接口,還可根據(jù)前兩個(gè)數(shù)據(jù)字節(jié)和11位標(biāo)識(shí)符對(duì)報(bào)文進(jìn)行濾波。
  MCP2515能夠發(fā)送和接收標(biāo)準(zhǔn)數(shù)據(jù)幀" title="數(shù)據(jù)幀">數(shù)據(jù)幀以及擴(kuò)展數(shù)據(jù)幀,并具有接收過(guò)濾和信息管理的功能。MCP2515通過(guò)其SI引腳同MCU進(jìn)行數(shù)據(jù)傳輸,最高數(shù)據(jù)傳輸速率可達(dá)1Mbps。MCU可以通過(guò)MCP2515與CAN總線上的其他MCU進(jìn)行通信。MCP2515內(nèi)含三個(gè)14 字節(jié)的發(fā)送緩沖器,二個(gè)14字節(jié)的接收緩沖器,并且具有靈活的中斷能力、幀屏蔽和過(guò)濾、幀優(yōu)先級(jí)設(shè)定等特性。
  MCP2515的主要功能參數(shù):(1)支持CAN協(xié)議2.0A/2.0B;(2)最大" title="最大">最大可編程波特率為1Mbps;(3)有標(biāo)準(zhǔn)幀和擴(kuò)展幀兩種數(shù)據(jù)幀可供選擇,每個(gè)幀中的數(shù)據(jù)段長(zhǎng)可為0~8字節(jié);(4)支持遠(yuǎn)程幀;(5)內(nèi)含3個(gè)發(fā)送緩沖器和2個(gè)接收緩沖器,并且其優(yōu)先級(jí)可編程設(shè)定;(6)內(nèi)含6個(gè)29字節(jié)的接收過(guò)濾器和2個(gè)29字節(jié)的接收過(guò)濾屏蔽器;(7)具有(loop-back)自環(huán)檢測(cè)模式;(8)標(biāo)準(zhǔn)幀數(shù)據(jù)段的前兩個(gè)字節(jié)的單獨(dú)過(guò)濾功能。


  圖1為MCP2515的內(nèi)部結(jié)構(gòu)原理圖,其中CAN模塊包括CAN協(xié)議機(jī)和發(fā)送、接收緩沖器以及他們的屏蔽器、過(guò)濾器。CAN協(xié)議機(jī)主要負(fù)責(zé)與CAN總線的接口,SPI接口邏輯負(fù)責(zé)實(shí)現(xiàn)與MCU的接口,而緩沖器、過(guò)濾器組和控制邏輯以及與之相關(guān)的位定時(shí)發(fā)生器、控制和中斷寄存器則負(fù)責(zé)實(shí)現(xiàn)各種工作模式的設(shè)定和操作控制。MCP2515芯片在CAN總線上的數(shù)據(jù)接收是通過(guò)2個(gè)接收緩沖器、2個(gè)接收屏蔽器、6個(gè)接收過(guò)濾器的組合來(lái)實(shí)現(xiàn)的。CAN總線上只有同時(shí)滿足至少任意一個(gè)接收屏蔽器和一個(gè)接收過(guò)濾器的條件的幀,才可以進(jìn)入接收緩沖器。MCU可以通過(guò)SPI接口來(lái)讀取MCP2515接收緩沖器里的數(shù)據(jù)。MCP2515對(duì)CAN總線的數(shù)據(jù)發(fā)送則沒(méi)有限制,只要用MCU通過(guò)SPI接口將待發(fā)送的數(shù)據(jù)寫(xiě)入MCP2515的發(fā)送緩沖器,然后再調(diào)用RTS(發(fā)送請(qǐng)求)命令即可將數(shù)據(jù)發(fā)送到CAN總線上。MCU通過(guò)使用標(biāo)準(zhǔn)SPI讀寫(xiě)命令對(duì)MCP2515寄存器進(jìn)行讀寫(xiě)操作。
  MCP2515具有靈活的中斷管理功能。它有8個(gè)中斷源,包括發(fā)送、接收中斷、各種錯(cuò)誤中斷以及總線喚醒中斷等。MCU可以通過(guò)對(duì)MCP2515的中斷允許控制寄存器CANINTE的設(shè)置來(lái)設(shè)定和屏蔽各種中斷的發(fā)生條件,并可以通過(guò)讀取MCP2515的中斷標(biāo)志位寄存器CANINTE或者讀取CANSTAT寄存器中的ICOD部分來(lái)判斷當(dāng)前中斷的中斷源。
2 緩沖管理的驅(qū)動(dòng)實(shí)現(xiàn)
2.1 驅(qū)動(dòng)框架和流程

  按照WINCE的標(biāo)準(zhǔn)的分層結(jié)構(gòu)來(lái)實(shí)現(xiàn)MCP2515的驅(qū)動(dòng),由于分層結(jié)構(gòu)的WINCE驅(qū)動(dòng)程序和操作系統(tǒng)內(nèi)核是緊密結(jié)合在一起的,調(diào)試驅(qū)動(dòng)時(shí)效率很低,而且這種方式實(shí)現(xiàn)的驅(qū)動(dòng),功能也不夠靈活,所以本文不再采用這種方式,而是直接在EVC下用SPI接口的方式來(lái)操作MCP2515芯片。硬件采用三星的ARM內(nèi)核的S3C2440A,該CPU帶有2通道SPI口,可以直接和MCP2515帶的SPI相連。S3C2440A通過(guò)SPI口就可以操作MCP2515芯片,實(shí)現(xiàn)CAN協(xié)議的數(shù)據(jù)收發(fā)。
  在CAN總線中,各種在CAN總線上傳輸?shù)臄?shù)據(jù)幀都被分配一個(gè)惟一的標(biāo)識(shí)符,每個(gè)節(jié)點(diǎn)根據(jù)這些標(biāo)識(shí)符來(lái)確定是否接收這些幀。當(dāng)然還必須與過(guò)濾器及屏蔽器配合,共同決定是否接收數(shù)據(jù)" title="接收數(shù)據(jù)">接收數(shù)據(jù)。
  本文提到的CAN總線分成父設(shè)備和子設(shè)備,子設(shè)備會(huì)主動(dòng)把自己的數(shù)據(jù)上傳給父設(shè)備,父設(shè)備收到數(shù)據(jù)后,對(duì)這些數(shù)據(jù)進(jìn)行進(jìn)一步的處理,例如,在屏幕上以圖表的形式顯示出來(lái)等。圖2顯示了CAN總線的網(wǎng)絡(luò)結(jié)構(gòu)。

?

?


  CAN父設(shè)備就是一個(gè)帶有MCP2515芯片的ARM嵌入式系統(tǒng)。CAN子設(shè)備也可以是一個(gè)帶MCP2515的嵌入式系統(tǒng),也可以是其他一些CAN設(shè)備。本文中主要介紹MCP2515在CAN父設(shè)備上" title="設(shè)備上">設(shè)備上的驅(qū)動(dòng)程序?qū)崿F(xiàn)。圖3是驅(qū)動(dòng)程序框圖。
  MCP2515主要提供了狀態(tài)查詢以及中斷兩種數(shù)據(jù)操作模式,本文中MCP2515主要采用狀態(tài)查詢模式進(jìn)行CAN總線數(shù)據(jù)的接收和發(fā)送。在系統(tǒng)上電后,先對(duì)MCP2515芯片進(jìn)行初始化的工作,主要是設(shè)置MCP2515芯片的相關(guān)寄存器的值,如設(shè)置波特率,屏蔽寄存器,過(guò)濾寄存器等。初始化工作完成后,開(kāi)啟一個(gè)線程負(fù)責(zé)收發(fā)數(shù)據(jù)。如果發(fā)送緩沖中有數(shù)據(jù)需要發(fā)送,則發(fā)送數(shù)據(jù),否則,查詢MCP2515的CANINTF寄存器的第0和1兩位,如果有數(shù)據(jù)則接收數(shù)據(jù),然后判斷該幀ID是否在父設(shè)備上注冊(cè),如果已注冊(cè),則把數(shù)據(jù)放到接收緩沖區(qū)中,否則,就丟掉繼續(xù)循環(huán),直到這個(gè)線程終止。
2.2 接收緩沖
  在驅(qū)動(dòng)中,為了保證接收的數(shù)據(jù)不會(huì)丟失,需要添加一個(gè)緩沖,用來(lái)緩存接收到的數(shù)據(jù)。在接收緩沖中,完全以幀的形式存放,方便后續(xù)的數(shù)據(jù)處理。在CAN總線中,主要有以下的幾種幀:
  數(shù)據(jù)幀:數(shù)據(jù)幀攜帶數(shù)據(jù)從發(fā)送器至接收器。
  遠(yuǎn)程幀:總線單元發(fā)出遠(yuǎn)程幀,請(qǐng)求發(fā)送具有同一識(shí)別符的數(shù)據(jù)幀。
  錯(cuò)誤幀:任何單元檢測(cè)到總線錯(cuò)誤就發(fā)出錯(cuò)誤幀。
  過(guò)載幀:過(guò)載幀用以在先行的和后續(xù)的數(shù)據(jù)幀(或遠(yuǎn)程幀)之間提供附加的延時(shí)。
  當(dāng)然,驅(qū)動(dòng)程序并不緩存所有的幀,只緩存需要的數(shù)據(jù)幀和遠(yuǎn)程幀,以下是驅(qū)動(dòng)中定義幀結(jié)構(gòu)的數(shù)據(jù)成員:
  DWORD      dwID;
  BOOL      bRemoteFlag;
  BOOL      bExternFlag;
  BYTE      DLCLen;
  BYTE      Data[9];
  結(jié)構(gòu)名稱為CAN_RECV_FRAME,dwID為幀ID,bRemoteFlag是遠(yuǎn)程幀標(biāo)志,bExternFlag 為擴(kuò)展幀標(biāo)志,DLCLen是數(shù)據(jù)長(zhǎng)度,它可以是0~8中的任何數(shù)值,Data[9]是幀數(shù)據(jù)的緩沖區(qū),最多使用其中8個(gè)字節(jié)。然后定義CList類型的成員變量m_RevList作為一個(gè)接收的隊(duì)列:
  CListm_RevList;
  在對(duì)緩沖區(qū)初始化時(shí),一次就分配了足夠的數(shù)據(jù)空間,而不必在使用時(shí)再動(dòng)態(tài)申請(qǐng)內(nèi)存,這樣保證了系統(tǒng)占用的內(nèi)存資源的確定性。線程在存取緩沖區(qū)時(shí)必須要事先鎖定,保證在一個(gè)時(shí)刻只有一個(gè)線程對(duì)緩沖區(qū)進(jìn)行存取操作。為了提高對(duì)資源的利用率,驅(qū)動(dòng)中把緩沖變成一個(gè)循環(huán)隊(duì)列,再定義了一個(gè)RECV_FRAME_USE的結(jié)構(gòu)來(lái)管理緩沖區(qū),該結(jié)構(gòu)的數(shù)據(jù)成員如下:
  POSITION     pHead;
  POSITION     pTail;
  Int        iLen;
  pHead是頭指針,pTail是尾指針,iLen為隊(duì)列使用長(zhǎng)度。有了RECV_FRAME_USE這個(gè)結(jié)構(gòu)后,緩沖區(qū)就成了一個(gè)幀的循環(huán)隊(duì)列。在系統(tǒng)收到幀時(shí),就把該幀放到隊(duì)列的后面。如果數(shù)據(jù)緩沖區(qū)已滿,則清空頭一幀,實(shí)現(xiàn)先進(jìn)先出。在沒(méi)有加上過(guò)濾以前,收到的總線上的所有的數(shù)據(jù)幀都放在緩沖中。
2.3 發(fā)送緩沖
  發(fā)送緩沖區(qū)和接收緩沖區(qū)不同,接收緩沖區(qū)之所以這樣設(shè)計(jì),是因?yàn)樵贛CP2515收到數(shù)據(jù)后,要進(jìn)行解幀,把幀ID、幀的類型、數(shù)據(jù)長(zhǎng)度和數(shù)據(jù)這些信息分開(kāi),分別存放在幀結(jié)構(gòu)的對(duì)應(yīng)變量中,這樣可方便后續(xù)的處理。但是在發(fā)送時(shí)必須先進(jìn)行組幀,而且要讓MCP2515把數(shù)據(jù)發(fā)送出去,必須把幀的數(shù)據(jù)(如幀ID、何種幀、數(shù)據(jù)的長(zhǎng)度以及數(shù)據(jù)等)按MCP2515的要求,送到MCP2515相應(yīng)寄存器中的對(duì)應(yīng)位。所以,在組織發(fā)送數(shù)據(jù)時(shí),必須把要發(fā)送的數(shù)據(jù)按照MCP2515的寄存器要求進(jìn)行組織,這樣在發(fā)送時(shí),直接把組織好的數(shù)據(jù)逐字節(jié)送到對(duì)應(yīng)的MCP2515的寄存器即可。MCP2515有三個(gè)14字節(jié)SRAM發(fā)送緩沖,并映射到存儲(chǔ)器中。其中第一字節(jié)TXBNCTRL 是與報(bào)文緩沖器相關(guān)的控制寄存器。該寄存器中的信息決定了報(bào)文在何種條件下被發(fā)送,并在報(bào)文發(fā)送時(shí)指示其狀態(tài)。用5個(gè)字節(jié)來(lái)裝載標(biāo)準(zhǔn)和擴(kuò)展標(biāo)識(shí)符以及其他報(bào)文仲裁信息。最后8個(gè)字節(jié)用來(lái)裝載等待發(fā)送的報(bào)文的8個(gè)可能的數(shù)據(jù)字節(jié)。所以,在發(fā)送緩沖區(qū)中,只保存5個(gè)字節(jié)的標(biāo)準(zhǔn)和擴(kuò)展標(biāo)識(shí)符以及其他報(bào)文仲裁信息,8個(gè)字節(jié)用來(lái)保存發(fā)送的數(shù)據(jù)。在驅(qū)動(dòng)中,定義了一個(gè)名為MCP2515_SEND_BUFFER的發(fā)送緩沖區(qū),以下是該緩沖區(qū)的數(shù)據(jù)成員。
  DWORD    dwWritePointer;
  DWORD    dwReadPointer;
  BYTE     Data[MAX_SEND_LEN]
  該緩沖區(qū)也是一個(gè)循環(huán)緩沖,dwWritePointer為發(fā)送緩沖的寫(xiě)指針,dwReadPointer為發(fā)送緩沖的讀指針,Data就是存放幀數(shù)據(jù)的隊(duì)列,MAX_SEND_LEN為隊(duì)列的最大長(zhǎng)度。該隊(duì)列的數(shù)據(jù)格式是:長(zhǎng)度+5個(gè)字節(jié)標(biāo)示符+數(shù)據(jù)。因?yàn)閿?shù)據(jù)的長(zhǎng)度最大為8個(gè)字節(jié),得出長(zhǎng)度最大就是13個(gè)字節(jié)。所以,長(zhǎng)度用BYTE型就可以表示了,這樣pData存放的數(shù)據(jù)就很規(guī)整。在發(fā)送時(shí),從pData中取走一幀后,直接把前5個(gè)字節(jié)標(biāo)準(zhǔn)和擴(kuò)展標(biāo)識(shí)符以及其他報(bào)文仲裁信息和后面數(shù)據(jù)字節(jié)送到MCP2515對(duì)應(yīng)對(duì)寄存器即可,不用解幀和組幀過(guò)程,從而加快發(fā)送進(jìn)程。
2.4 雙注冊(cè)機(jī)制
  MCP2515芯片具有兩個(gè)驗(yàn)收屏蔽寄存器(分別對(duì)應(yīng)不同的接收緩沖器)以及六個(gè)驗(yàn)收過(guò)濾寄存器,它們共同來(lái)決定報(bào)文是否應(yīng)被載入接收緩沖器。 一旦報(bào)文集成緩沖器(MBA)接收到有效報(bào)文,報(bào)文中的標(biāo)識(shí)符字段將與過(guò)濾寄存器中的值進(jìn)行比較。如果兩者匹配,該報(bào)文將被載入相應(yīng)的接收緩沖器。濾波屏蔽寄存器用來(lái)確定濾波器對(duì)標(biāo)識(shí)符中的哪些位進(jìn)行校驗(yàn),這樣可以直接屏蔽一些不希望收到的數(shù)據(jù)。這一機(jī)制對(duì)于所有的有MCP2515芯片的設(shè)備都是有用的。在利用緩沖區(qū)來(lái)緩存收到的數(shù)據(jù)后,畢竟驅(qū)動(dòng)程序中的緩沖區(qū)大小受限,有時(shí)并不需要把所有收到的數(shù)據(jù)放在緩沖中,所以對(duì)進(jìn)入緩沖區(qū)的數(shù)據(jù)再加上一次過(guò)濾,即在父設(shè)備上注冊(cè)的機(jī)制。只有在父設(shè)備上注冊(cè)了ID的子設(shè)備,父設(shè)備才會(huì)把數(shù)據(jù)放到數(shù)據(jù)緩沖區(qū)中。在父設(shè)備的驅(qū)動(dòng)中,有一個(gè)列表專門(mén)用來(lái)保存子設(shè)備注冊(cè)的ID,每次父設(shè)備收到數(shù)據(jù)在放到緩沖區(qū)中以前,都會(huì)比較一下,在列表中有沒(méi)有這個(gè)ID,如有就放到緩沖區(qū)中,如沒(méi)有則丟掉。這樣又可以屏蔽掉總線上的一些無(wú)關(guān)的數(shù)據(jù),從而提高了效率。
  本文詳細(xì)介紹了MCP2515在WINCE中的實(shí)現(xiàn)過(guò)程和主要技術(shù),但是限于篇幅,沒(méi)能給出詳細(xì)的軟件源程序。實(shí)踐證明,該驅(qū)動(dòng)在CAN總線實(shí)際的應(yīng)用中效果明顯,既提高了開(kāi)發(fā)的效率,又實(shí)現(xiàn)了更靈活的功能。
參考文獻(xiàn)
1 Boling D.Microsoft Windows CE程序設(shè)計(jì).北京:北京大學(xué)出版社,1998
2 饒運(yùn)濤.現(xiàn)場(chǎng)總線CAN原理與應(yīng)用技術(shù).北京:北京航空航天大學(xué)出版社,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

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。