《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 通信與網(wǎng)絡(luò) > 業(yè)界動態(tài) > 汽車ECU標(biāo)定系統(tǒng)CAN驅(qū)動模塊的實現(xiàn)

汽車ECU標(biāo)定系統(tǒng)CAN驅(qū)動模塊的實現(xiàn)

2016-05-26
關(guān)鍵詞: ECU CAN總線 串口通信 編程接口

1  前言

        標(biāo)定是指根據(jù)整車的各種性能要求(如動力性、經(jīng)濟(jì)性、排放及輔助功能等),來調(diào)整、優(yōu)化和確定整車上各ECU(如發(fā)動機(jī)、AT等各子系統(tǒng) ECU)控制參數(shù)的控制算法。標(biāo)定系統(tǒng)主要是由上位機(jī)和底層ECU這二部分組成,因此,上位機(jī)和底層ECU的通信方式對整個標(biāo)定系統(tǒng)的性能起到了至關(guān)重要的作用。目前,一般的標(biāo)定系統(tǒng)都是采用基于串行口的點對點的通信方式,這種通信方式容易實現(xiàn),但存在著通信速度較慢、可靠性較低等缺陷。這里我們采用的是CAN總線的通信方式,相對串口通信,基于CAN總線的通信方式具有通信可靠[1]、傳輸速度快、可實現(xiàn)在線編程等優(yōu)點。

2  總體設(shè)計

       CAN通信可視為系統(tǒng)的一個I/O字符流設(shè)備[3],它在完成普通收發(fā)功能的同時,還要能實現(xiàn)驅(qū)動程序必備的設(shè)備無關(guān)性。即驅(qū)動程序應(yīng)將系統(tǒng)所有的硬件特性封裝起來,為使用該設(shè)備的應(yīng)用程序提供與硬件無關(guān)的、通用的編程接口,應(yīng)用層程序編寫人員無需了解設(shè)備的原理,即可順利實現(xiàn)對設(shè)備的控制,通過該設(shè)備實現(xiàn)可靠的數(shù)據(jù)交換。另外,針對CAN通信和嵌入式系統(tǒng)的實時性要求,該驅(qū)動程序要求收發(fā)數(shù)據(jù)代碼可靠,延遲短,占用系統(tǒng)時間短,中斷執(zhí)行時間短,關(guān)閉中斷時間短,并在收發(fā)錯誤和發(fā)生異常情況時,向應(yīng)用程序匯報。另外,該驅(qū)動程序需要監(jiān)控CAN控制器的工作狀態(tài),在出現(xiàn)致命錯誤和脫離總線時,為CAN模塊復(fù)位,并向系統(tǒng)匯報。

圖1 驅(qū)動程序總體結(jié)構(gòu)圖

       基于以上需求分析,結(jié)合其他OS中實現(xiàn)I/O串行設(shè)備的驅(qū)動方案及CAN的總線要求特點,設(shè)計總體驅(qū)動程序結(jié)構(gòu)如圖1。   

3  CAN驅(qū)動模塊的實現(xiàn)

       基于以上總體設(shè)計框架,首先定義一個CAN類來封裝CAN通信中的數(shù)據(jù)結(jié)構(gòu)和函數(shù),最下面一層為中斷級程序,中斷處理程序在每次CAN控制器完成收發(fā)時,喚醒驅(qū)動程序,進(jìn)行下一步工作。在中斷處理程序中,根據(jù)不同的中斷向量來確定當(dāng)前發(fā)生的是發(fā)送完成中斷還是接受完成中斷,并完成相應(yīng)工作。中間一層為底層驅(qū)動程序,底層驅(qū)動程序主要是通過對CAN控制器寄存器的讀寫,完成對CAN端口的配置和狀態(tài)檢測等工作,同時為設(shè)備無關(guān)軟件和用戶程序提供接口。在這一層中,必須要建立一個環(huán)狀緩沖結(jié)構(gòu),該緩沖由一個接收環(huán)狀緩沖區(qū)和一個發(fā)送環(huán)狀緩沖區(qū)組成,其數(shù)據(jù)結(jié)構(gòu)如下代碼所示,對于每個環(huán)狀緩沖區(qū),設(shè)計了一個存入指針指向下一個待存入CANMsg的存入地址,一個讀出指針指向緩沖區(qū)下一個待取出的(最舊的)CANMsg的地址,一個計數(shù)器記錄目前緩沖區(qū)中有多少個CANMsg待取出,一個信號量,用于與應(yīng)用程序交換消息。接收環(huán)狀緩沖區(qū)用于緩沖接收到的總線消息,等待應(yīng)用程序處理,發(fā)送環(huán)狀緩沖區(qū)用于緩沖應(yīng)用程序發(fā)送出的消息,等待發(fā)送中斷程序來處理。

typedef struct{   //環(huán)形緩沖區(qū)的數(shù)據(jù)結(jié)構(gòu)

INT16U   RingBufRxCtr;       //接收計數(shù)器

OS_EVENT *RingBufRxSem;    //信號量

CAN_msg  *RingBufRxInPtr;    //接收緩沖區(qū)的存入指針

CAN_msg  *RingBufRxOutPtr;  //接收緩沖區(qū)的讀出指針

CAN_msg  RingBufRx[CAN_RX_BUF_SIZE];  //接收緩沖區(qū)的消息存儲

INT16U   RingBufTxCtr;  //發(fā)送計數(shù)器

OS_EVENT *RingBufTxSem;

CAN_msg  *RingBufTxInPtr;    //發(fā)送緩沖區(qū)的存入指針

CAN_msg  *RingBufTxOutPtr;  //發(fā)送緩沖區(qū)的讀出指針

CAN_msg  RingBufTx[CAN_TX_BUF_SIZE];  //發(fā)送緩沖區(qū)的消息存儲

}CAN_RING_BUF;

 3.1 底層驅(qū)動

       底層驅(qū)動模塊為我們應(yīng)用程序提供了接收和發(fā)送消息的接口函數(shù)。

圖2  CAN接收消息

       當(dāng)接收消息時[3],如圖2所示,應(yīng)用程序在信號量處等待;收到一個消息后,ISR從串行端口讀入消息,將其存入環(huán)型緩沖區(qū)。然后ISR發(fā)出信號量,通知在等待串口數(shù)據(jù)的任務(wù)已收到一個消息。等待任務(wù)收到信號量后,進(jìn)入就緒狀態(tài),準(zhǔn)備被OS調(diào)度器激活。當(dāng)內(nèi)核調(diào)度該任務(wù)運行時,該任務(wù)從環(huán)狀緩沖區(qū)中取出消息,完成接收消息的過程。

void CAN_GetMsg(CAN_msg *msg){

INT8U   oserr;

OS_CPU_SR cpu_sr;

CAN_RING_BUF *pbuf;

pbuf = &ringbuf;

OSSemPend(pbuf->RingBufRxSem,0,&oserr);   //等待信號量

OS_ENTER_CRITICAL();//關(guān)中斷

pbuf->RingBufRxCtr--;//接收計數(shù)器減1

CopyMsg(pbuf->RingBufRxOutPtr++,msg); //從環(huán)形緩沖區(qū)中取出信號量         

if(pbuf->RingBufRxOutPtr==&pbuf->RingBufRx[CAN_RX_BUF_SIZE]) {pbuf->RingBufRxOutPtr= &pbuf->RingBufRx[0];

//如果環(huán)形緩沖區(qū)的讀出指針達(dá)到緩沖區(qū)的最末端,將其改為指向緩沖區(qū)的首地址  }

OS_EXIT_CRITICAL();  //開中斷,允許CPU響應(yīng)中斷   }

        發(fā)送CAN消息與接受消息類似。后臺進(jìn)程將欲發(fā)送的消息幀存儲于發(fā)送環(huán)狀緩沖區(qū)中。當(dāng)CAN端口準(zhǔn)備發(fā)送一幀消息時,產(chǎn)生一個中斷,CAN消息從緩沖區(qū)中取出,并由ISR輸出[4]。但其中出現(xiàn)了一個問題:CAN端口只能在發(fā)送上一個數(shù)據(jù)結(jié)束的時候才會產(chǎn)生一個中斷,這個產(chǎn)生中斷的時刻與我們需要執(zhí)行中斷任務(wù)的時間是不一致的。解決這個問題的方法就是,禁止發(fā)送端中斷使能直到需要再發(fā)送消息為止。在系統(tǒng)啟動時,禁止發(fā)送中斷,發(fā)送一個啟動消息幀,這時發(fā)送完成中斷標(biāo)志位已經(jīng)被置位,但由于發(fā)送中斷使能位為低,所以無法發(fā)生中斷,系統(tǒng)繼續(xù)執(zhí)行。當(dāng)需發(fā)送第一個消息時,將該消息放入發(fā)送環(huán)狀緩沖區(qū),然后運行發(fā)送中斷,這時,上一次發(fā)送消息完成中斷產(chǎn)生,發(fā)送該消息。在發(fā)送消息結(jié)束時,若發(fā)送環(huán)狀緩沖區(qū)中有其他數(shù)據(jù)需要發(fā)送,則清中斷源,等待該消息發(fā)送完成中斷產(chǎn)生,來發(fā)送下一個消息,若沒有其他數(shù)據(jù)需要被發(fā)送,則直接禁止發(fā)送中斷,將該消息發(fā)送完成時產(chǎn)生的中斷保留到下一次有消息需要發(fā)送時發(fā)生。

圖3  CAN發(fā)送消息

       發(fā)送消息的方法如圖3。當(dāng)發(fā)送環(huán)狀緩沖區(qū)已滿時,信號量作為指示,暫停發(fā)送任務(wù)。發(fā)送消息時,任務(wù)等待信號量。如果環(huán)狀緩沖區(qū)未滿,則任務(wù)繼續(xù)向環(huán)狀緩沖區(qū)存儲欲發(fā)送的消息。如果存儲的消息是緩沖區(qū)第一個字節(jié),則發(fā)送中斷允許,中斷程序準(zhǔn)備啟動。CAN發(fā)送ISR從環(huán)行緩沖區(qū)中取出最舊的消息,同時發(fā)送信號量,通知發(fā)送任務(wù),表明環(huán)狀緩沖區(qū)有空間接收另外的消息,接著ISR將消息從發(fā)送到總線上。其實現(xiàn)代碼如下所示:

void CAN_PutMsg(CAN_msg *msg) {

INT8U oserr;

OS_CPU_SR cpu_sr;

CAN_RING_BUF *pbuf;

pbuf = &ringbuf;

OSSemPend(pbuf->RingBufTxSem, 0, &oserr);   //等待信號量

OS_ENTER_CRITICAL();//關(guān)中斷

pbuf->RingBufTxCtr++;   //發(fā)送計數(shù)器加1

CopyMsg(msg, pbuf->RingBufTxInPtr++);  //將消息放入環(huán)形緩沖區(qū)

if(pbuf->RingBufTxInPtr==&pbuf->RingBufTx[CAN_TX_BUF_SIZE]) {pbuf->RingBufTxInPtr=&pbuf->RingBufTx[0];

     }

if (pbuf->RingBufTxCtr==1) {

     CAN_TxIntEn();//為環(huán)形緩沖區(qū)的第一則消息,開發(fā)送中斷

     }

     OS_EXIT_CRITICAL();

}

3.2 中斷服務(wù)程序

       根據(jù)前面談到發(fā)送和接收消息的軟件結(jié)構(gòu),在CAN初始化時就要求CAN的接收中斷處入開啟狀態(tài),而發(fā)送中斷僅僅是在發(fā)送緩沖區(qū)里面有了第一則消息后再開啟的,因此在這里設(shè)計兩個接口函數(shù),CAN.TxIntEn()和CAN.TxIntDis(),分別將發(fā)送屏蔽位置1(允許發(fā)送完成中斷)和置0(禁止發(fā)送完成中斷)。

圖4  發(fā)送接收中斷程序流程圖

        中斷級程序的核心就是CANRX_ISR()和CANTX_ISR(),它們由初始化時對該模塊的中斷設(shè)置寄存器設(shè)置的中斷級別。如圖4所示,若為接收完成中斷,則清除中斷源,將接收到的消息放入接收緩沖區(qū);將該消息存入接收緩沖區(qū)存入指針?biāo)赶虻牡刂?,將該指針向下移動,接收緩沖區(qū)計數(shù)器加1,并發(fā)出信號量通知應(yīng)用程序有新的消息已經(jīng)接收到,若有任務(wù)正在等待CAN上的新消息,則該任務(wù)進(jìn)入就緒狀態(tài)等待OS的調(diào)度。若為發(fā)送完成中斷,則將發(fā)送緩沖區(qū)的待發(fā)送消息讀出;將有待發(fā)送消息且優(yōu)先級最高的一個中讀取最舊的消息(緩沖區(qū)取出指針?biāo)赶虻南ⅲ?,發(fā)送緩沖區(qū)計數(shù)器減1,發(fā)出信號量通知應(yīng)用程序有一個消息被發(fā)出,并匯報當(dāng)前發(fā)送緩沖區(qū)的狀態(tài);還應(yīng)判斷是否為最后一個待發(fā)送的消息,若不是,則清除中斷源并將消息發(fā)送到總線上,若是最后一個,則禁止發(fā)送完成中斷后發(fā)送該消息,將這個發(fā)送完成中斷保留到應(yīng)用程序下一次發(fā)送消息的時候允許并產(chǎn)生。

3.3 應(yīng)用

       該驅(qū)動程序的應(yīng)用,如下代碼所示,這里使用的是uCOS-II,首先定義一個CAN消息對象(msg)和一個環(huán)狀緩沖區(qū)數(shù)據(jù)結(jié)構(gòu)(CANRingBuf),在主程序中,初始化OS以后調(diào)用Ringbuf_Init()函數(shù)初始化環(huán)形緩存區(qū),然后調(diào)用CAN_Init()函數(shù)初始化CAN端口。在啟動OS后,用戶就可用在任何任務(wù)中調(diào)用CAN_PutMsg(CAN_msg *msg)和CAN_GetMsg(CAN_msg *msg)發(fā)送和接收總線消息了。

CAN_msg msg;

CAN_RING_BUF CANRingBuf;

void main(void) { 

OSInit();

Ringbuf_Init();

CAN_Init();

/* Creat task1 */

       OSStart();    }

void task1 (void * data)

{     CAN_PutMsg(&msg);

CAN_GettMsg(&msg);

}

4  結(jié)束語

       通過改變芯片總線頻率、CAN通信速率這樣多次反復(fù)不斷的調(diào)試,此CAN驅(qū)動在實時操作系統(tǒng)上運行穩(wěn)定可靠,未出現(xiàn)數(shù)據(jù)丟失,較好的實現(xiàn)了上位機(jī)與ECU的通信,因此,具有很強(qiáng)的實用價值。


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
亚洲一区二区三区欧美 | 性欧美xxxx视频在线观看| 91久久极品少妇xxxxⅹ软件| 国内精品一区二区| 国产亚洲一区在线| 国产一区二区三区免费不卡 | 国产精品黄视频| 欧美日韩一区二区三区免费看| 欧美大学生性色视频| 麻豆精品一区二区综合av| 久久综合九色99| 久久这里只有| 欧美成人亚洲成人| 欧美精品九九99久久| 欧美人与性动交cc0o| 欧美片网站免费| 欧美日韩精品欧美日韩精品一| 欧美日韩高清不卡| 欧美性猛交视频| 国产伦精品一区二区三区照片91 | av不卡在线| 亚洲图片自拍偷拍| 亚洲欧美日韩精品久久亚洲区| 午夜精品理论片| 久久精品99无色码中文字幕| 久久美女性网| 欧美高清在线观看| 欧美日本成人| 国产精品激情| 国产一区二区三区高清| 在线成人激情黄色| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲老司机av| 亚洲视频一起| 欧美一级大片在线免费观看| 久久久噜噜噜久久久| 模特精品裸拍一区| 欧美日韩国产一区精品一区| 国产精品伦一区| 国产一区二区三区在线观看免费 | 亚洲三级毛片| 亚洲欧美日本视频在线观看| 久久国产手机看片| 日韩视频免费看| 午夜精品福利一区二区蜜股av| 久久久久久久999| 欧美黄色aaaa| 国产精品色在线| 狠久久av成人天堂| 亚洲精选大片| 欧美在线日韩精品| 99re在线精品| 欧美在线日韩| 欧美激情一区二区| 国产美女诱惑一区二区| 有码中文亚洲精品| 亚洲无限乱码一二三四麻| 久久精品亚洲热| 亚洲一区日韩在线| 久久性天堂网| 欧美午夜女人视频在线| 国模吧视频一区| 亚洲理论电影网| 久久国产精品高清| 亚洲特级毛片| 欧美不卡一卡二卡免费版| 国产精品久久亚洲7777| 亚洲国产精品999| 亚洲欧美一区二区原创| 亚洲免费观看| 久久久噜噜噜久久中文字幕色伊伊| 欧美日韩国产精品专区| 精品91在线| 亚洲欧美在线aaa| 中国女人久久久| 蜜臀av国产精品久久久久| 国产精品无码专区在线观看| 亚洲黄色在线| 久久精品视频在线免费观看| 亚洲欧美成人精品| 欧美伦理影院| 1204国产成人精品视频| 午夜精品成人在线| 亚洲图片你懂的| 欧美激情精品久久久久久久变态| 国产三级精品三级| 亚洲小说春色综合另类电影| 日韩一级在线| 免费在线国产精品| 国内精品久久久久久久影视蜜臀| 一本久道久久综合狠狠爱| 亚洲欧洲一二三| 久久久www成人免费无遮挡大片| 欧美性做爰毛片| 日韩视频一区| 日韩一级成人av| 免费在线日韩av| 国产综合香蕉五月婷在线| 一区二区精品在线观看| 亚洲日本一区二区三区| 久久久久国产精品厨房| 国产精品一区二区在线| 夜久久久久久| 一区二区高清视频| 欧美77777| 一区在线观看视频| 亚洲国产欧美久久| 久久综合九色综合欧美就去吻 | 欧美一区国产一区| 国产精品日韩一区二区三区| 99国产精品| 在线视频一区二区| 欧美日韩国产综合视频在线观看| 亚洲第一在线综合网站| 亚洲欧洲一区二区三区| 免费在线成人av| 在线日韩av永久免费观看| 久久精品观看| 老色批av在线精品| 亚洲国产mv| 亚洲精品综合| 欧美日本不卡视频| 99精品国产在热久久| 亚洲午夜小视频| 国产精品成av人在线视午夜片| 一本色道久久综合一区| 亚洲欧美激情诱惑| 国产精品亚洲产品| 性做久久久久久久免费看| 久久精品av麻豆的观看方式| 国产一区欧美| 亚洲国产精品精华液2区45 | 国产毛片一区| 久久精品国产亚洲一区二区三区| 久久久水蜜桃av免费网站| 狠狠狠色丁香婷婷综合久久五月| 亚洲第一区中文99精品| 欧美成在线观看| 亚洲美女av网站| 亚洲影院在线| 国产精品中文字幕欧美| 久久国产精品久久久久久久久久| 美女脱光内衣内裤视频久久网站| 亚洲第一天堂无码专区| 一区二区三区欧美视频| 国产精品久久久久久久久久久久久 | 欧美视频一区二区三区…| 亚洲深夜福利网站| 欧美在线日韩精品| 在线成人性视频| 一区二区三欧美| 国产精品视频久久一区| 久久国产精品99久久久久久老狼 | 日韩视频精品在线| 欧美亚洲一区三区| 在线成人性视频| 亚洲一级二级在线| 国产在线拍偷自揄拍精品| 亚洲欧洲一区二区在线观看| 欧美日韩亚洲免费| 欧美中文日韩| 欧美另类人妖| 亚洲欧美视频在线| 欧美成人国产| 亚洲图片在线| 久久婷婷蜜乳一本欲蜜臀| 亚洲日本在线视频观看| 午夜在线不卡| 亚洲国产一二三| 欧美一区二区三区精品电影| 亚洲国产精品www| 性欧美8khd高清极品| 在线日本成人| 欧美一区二区福利在线| 在线观看亚洲精品视频| 亚洲女爱视频在线| 在线日韩av片| 欧美一区二区三区另类| 亚洲欧洲在线免费| 久久精品免费电影| 日韩一本二本av| 免费成人高清| 亚洲在线一区二区| 欧美高清在线精品一区| 小黄鸭精品密入口导航| 欧美精品一卡二卡| 欧美一区二区高清在线观看| 欧美日韩免费看| 91久久国产综合久久| 国产日韩欧美一区二区| 在线视频你懂得一区 | 亚洲伦理在线观看| 久久综合九色综合欧美就去吻| 亚洲素人在线| 欧美激情精品| 亚洲国产裸拍裸体视频在线观看乱了中文 | 中文久久乱码一区二区| 欧美国产成人在线| 欧美在线播放视频| 国产精品入口日韩视频大尺度|