新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 利用MCP2515的多路CAN總線接口及驅(qū)動(dòng)程序設(shè)計(jì)

利用MCP2515的多路CAN總線接口及驅(qū)動(dòng)程序設(shè)計(jì)

作者: 時(shí)間:2016-09-12 來(lái)源:網(wǎng)絡(luò) 收藏

CanBaudRatebaudrate;

CanFilter filter;

int br_flag;

int fi_flag;

} CanDevConfig;

其中,node_num為的節(jié)點(diǎn)號(hào)(0~4),baudrate為CAN總線通信速率,filter為報(bào)文濾波配置結(jié)構(gòu),br_flag用于標(biāo)識(shí)波特率配置是否有效,fi_flag用于標(biāo)識(shí)報(bào)文濾波配置是否有效。 baudrate和filter的數(shù)據(jù)結(jié)構(gòu)類型定義如下:

typedef enum {

_125kbps,

_250kbps,

_500kbps,

_1Mbps

} CanBaudRate;

typedef struct{

unsigned int mask_0;

unsigned int mask_1;

unsigned int filter_0;

unsigned int filter_1;

unsigned int filter_2;

unsigned int filter_3;

unsigned int filter_4;

unsigned int filter_5;

}CanFilter;

(2) 工作模式配置結(jié)構(gòu)體

typedef struct{

unsigned char node_num;

unsigned char oper_mode;

} CanDevMode;

其中,node_num意義同上,oper_mode表示該節(jié)點(diǎn)的工作模式。共有5種工作模式,分別是配置模式、休眠模式、僅監(jiān)聽(tīng)模式、回環(huán)模式和正常模式。一般設(shè)備都工作在正常模式。

3.1.3 環(huán)形數(shù)據(jù)接收緩沖區(qū)結(jié)構(gòu)體

typedef struct {

CanFrame can_recv_buf[RECV_BUF_SIZE];

int recv_pos;

int read_pos;

wait_queue_head_twq;

} CanDev;

其中,can_recv_buf為接收CAN報(bào)文幀環(huán)形數(shù)據(jù)緩沖區(qū),recv_pos和read_pos分別表示數(shù)據(jù)存入和讀出緩沖區(qū)的位置;wq定義的是一個(gè)等待隊(duì)列,用于實(shí)現(xiàn)阻塞型read操作。

3.2 驅(qū)動(dòng)程序接口

驅(qū)動(dòng)程序的接口主要分為3個(gè)部分: 初始化與退出函數(shù)接口,完成設(shè)備安裝和卸載等操作;文件系統(tǒng)接口,由file_operations數(shù)據(jù)結(jié)構(gòu)來(lái)完成;與設(shè)備的接口,完成對(duì)設(shè)備的讀/寫(xiě)等操作。

3.2.1 初始化與退出函數(shù)

在安裝驅(qū)動(dòng)程序時(shí),操作系統(tǒng)會(huì)調(diào)用初始化函數(shù)進(jìn)行設(shè)備注冊(cè)、設(shè)備初始化以及安裝中斷處理例程等操作。參考文獻(xiàn)[3]詳細(xì)論述了設(shè)備注冊(cè)的方法,而這里主要討論設(shè)備初始化時(shí)的配置方法。在本驅(qū)動(dòng)程序中,設(shè)備初始化分兩步:一是對(duì)9200的SPI控制器初始化,二是對(duì)5個(gè)初始化。

在卸載設(shè)備驅(qū)動(dòng)程序時(shí)會(huì)調(diào)用退出函數(shù),退出函數(shù)主要完成設(shè)備的注銷和中斷釋放。

參考文獻(xiàn)[3]詳細(xì)論述了中斷處理例程的安裝、設(shè)備注銷和中斷釋放的方法,此處不再詳述。

3.2.2 中斷接收服務(wù)例程

MCP2515收到CAN報(bào)文幀后,產(chǎn)生中斷并將INT引腳置低。9200響應(yīng)外部中斷,并調(diào)用和外部中斷相對(duì)應(yīng)的中斷處理例程。中斷處理例程共有3個(gè): at91_mcp2515_irq_handler_0響應(yīng)IRQ0的中斷,at91_mcp2515_irq_handler_1_2響應(yīng)IRQ1的中斷,at91_mcp2515_irq_handler_3_4響應(yīng)IRQ2的中斷。其中IRQ0只和一個(gè)MCP2515相連,而IRQ1和IRQ2分別被兩個(gè)MCP2515所共享。IRQ0和IRQ1的中斷處理流程分別如圖5和圖6所示,IRQ2與IRQ1的中斷處理流程相同。

圖5 IRQ0中斷處理流程

圖6 IRQ1中斷處理流程

需要注意的是,在圖5的處理流程中并沒(méi)有清中斷操作。這是因?yàn)椴捎昧薘X讀緩沖區(qū)指令讀取MCP2515 RX緩沖區(qū)中的數(shù)據(jù)。該指令操作結(jié)束后,MCP2515會(huì)自動(dòng)清除相應(yīng)的接收中斷標(biāo)志位。

3.2.3 文件系統(tǒng)接口定義

文件系統(tǒng)接口struct file_operations的成員全部是函數(shù)指針,這些指針指出了設(shè)備驅(qū)動(dòng)程序所提供的入口點(diǎn)位置。本驅(qū)動(dòng)程序所定義的file_operations為:

static struct file_operations at91_mcp2515_fops = {

owner: THIS_MODULE,

write: at91_mcp2515_write,

read:at91_mcp2515_read,

ioctl: at91_mcp2515_ioctl,

open: at91_mcp2515_open,

release:at91_mcp2515_release,

};

3.2.4 ioctl函數(shù)

ioctl函數(shù)用于對(duì)設(shè)備進(jìn)行配置。我們?cè)趇octl函數(shù)中實(shí)現(xiàn)了兩個(gè)命令: IOCTRL_CONFIG_CAN_DEV用于配置節(jié)點(diǎn)的CAN總線波特率和報(bào)文濾波,IOCTRL_SET_OPER_MODE用于配置節(jié)點(diǎn)的工作模式。這兩種配置命令所對(duì)應(yīng)的配置參數(shù)都是指向應(yīng)用層相應(yīng)數(shù)據(jù)結(jié)構(gòu)的指針,兩個(gè)配置結(jié)構(gòu)在3.1.2小節(jié)已經(jīng)介紹過(guò)了。

用IOCTRL_CONFIG_CAN_DEV命令配置波特率和報(bào)文濾波時(shí),在配置完成后,如果節(jié)點(diǎn)處于INACTIVE狀態(tài),則需要使能節(jié)點(diǎn)內(nèi)部的接收中斷,使能節(jié)點(diǎn)所對(duì)應(yīng)的外部中斷,并將節(jié)點(diǎn)狀態(tài)設(shè)置為ACTIVE。在通常情況下,通過(guò)ioctl函數(shù)對(duì)需要配置的節(jié)點(diǎn)執(zhí)行完 IOCTRL_CONFIG_CAN_DEV命令后,還要再對(duì)配置過(guò)的節(jié)點(diǎn)執(zhí)行IOCTRL_SET_OPER_MODE命令,使節(jié)點(diǎn)處于正常的工作模式。

3.2.5 關(guān)于競(jìng)爭(zhēng)問(wèn)題

本系統(tǒng)是單CPU系統(tǒng),采用Linux 2.4.19內(nèi)核,且是非搶占式的;同時(shí),此設(shè)計(jì)的驅(qū)動(dòng)程序也只允許一個(gè)進(jìn)程打開(kāi)并操作該設(shè)備。在這種情況下,驅(qū)動(dòng)程序中所涉及的競(jìng)爭(zhēng)問(wèn)題主要就是中斷處理程序內(nèi)核代碼和其他設(shè)備操作的內(nèi)核代碼之間的資源競(jìng)爭(zhēng)。在上文中所提到的所有設(shè)備操作中,都要通過(guò)9200的SPI接口與MCP2515進(jìn)行通信。 9200與MCP2515進(jìn)行通信都是以命令字節(jié)開(kāi)始的,并且在一個(gè)命令操作過(guò)程中(一般會(huì)連續(xù)傳輸多個(gè)字節(jié)),片選和時(shí)鐘是不能被禁用的,否則操作就會(huì)失敗。因此,MCP2515的一個(gè)完整的命令操作就是一個(gè)臨界區(qū)域,在對(duì)MCP2515進(jìn)行一個(gè)命令操作的過(guò)程中必須禁用所有的中斷,以保證命令操作的正常執(zhí)行。在驅(qū)動(dòng)程序中,采用local_irq_save和local_irq_restore函數(shù)對(duì)中斷禁用和恢復(fù),在這兩個(gè)函數(shù)調(diào)用之間,就是對(duì) MCP2515執(zhí)行一個(gè)命令操作的代碼。

結(jié)語(yǔ)

本文針對(duì)特有的應(yīng)用需求提出的多路和驅(qū)動(dòng)程序設(shè)計(jì),經(jīng)過(guò)測(cè)試,可以穩(wěn)定正常地運(yùn)行。關(guān)于驅(qū)動(dòng)程序的編譯和運(yùn)行方法,參考文獻(xiàn) [3]有很好的說(shuō)明。上層的測(cè)試程序編寫(xiě)也比較簡(jiǎn)單,但要注意數(shù)據(jù)結(jié)構(gòu)的定義和底層驅(qū)動(dòng)程序的一致性。本文側(cè)重介紹設(shè)計(jì)的基本方法和實(shí)現(xiàn)基本的功能。 MCP2515本身提供了許多的功能,在實(shí)現(xiàn)基本功能的基礎(chǔ)上,也可以根據(jù)自己的應(yīng)用需要再進(jìn)行功能擴(kuò)展。



評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉