linux can总线接收数据串口打包上传_【Linux应用】CAN总线编程
1 CAN總線簡介
CAN是控制器局域網(wǎng)絡(luò)(Controller Area Network,CAN)的簡稱,由德國BOSCH公司開發(fā),并最終成為國際標(biāo)準(zhǔn)(ISO 11898-1)。CAN總線主要應(yīng)用于工業(yè)控制和汽車電子領(lǐng)域,是國際上應(yīng)用最廣泛的現(xiàn)場總線之一。 CAN總線是一種串行通信協(xié)議,能有效地支持具有很高安全等級的分布實時控制。CAN總線的應(yīng)用范圍很廣,從高速的網(wǎng)絡(luò)到低價位的多路接線都可以使用CAN。在汽車電子行業(yè)里,使用CAN 連接發(fā)動機(jī)的控制單元、傳感器、防剎車系統(tǒng)等,傳輸速度可達(dá)1Mbps。與前面介紹的一般通信總線相比,CAN總線的數(shù)據(jù)通信具有突出的可靠性、實時性和靈活性,在汽車領(lǐng)域的應(yīng)用最為廣泛,世界上一些著名的汽車制造廠商都采用CAN總線來實現(xiàn)汽車內(nèi)部控制系統(tǒng)與各檢測和執(zhí)行機(jī)構(gòu)之間的數(shù)據(jù)通信。目前,CAN總線的應(yīng)用范圍已不僅僅局限于汽車行業(yè),而且已經(jīng)在自動控制、航空航天、航海、過程工業(yè)、機(jī)械工業(yè)、紡織機(jī)械、農(nóng)用機(jī)械、機(jī)器人、數(shù)控機(jī)床、醫(yī)療器械及傳感器等領(lǐng)域中得到了廣泛應(yīng)用。CAN總線規(guī)范從最初的CAN 1.2規(guī)范(標(biāo)準(zhǔn)格式)發(fā)展為兼容CAN 1.2規(guī)范的CAN 2.0規(guī)范(CAN 2.0A為標(biāo)準(zhǔn)格式,CAN 2.0B為擴(kuò)展格式),目前應(yīng)用的CAN器件大多符合CAN 2.0規(guī)范。
2 CAN總線的工作原理
當(dāng)CAN總線上的節(jié)點發(fā)送數(shù)據(jù)時,以報文形式廣播給網(wǎng)絡(luò)中的所有節(jié)點,總線上的所有節(jié)點都不使用節(jié)點地址等系統(tǒng)配置信息,只根據(jù)每組報文開頭的 11 位標(biāo)識符(CAN 2.0A 規(guī)范)解釋數(shù)據(jù)的含義來決定是否接收。這種數(shù)據(jù)收發(fā)方式稱為面向內(nèi)容的編址方案。
當(dāng)某個節(jié)點要向其他節(jié)點發(fā)送數(shù)據(jù)時,這個節(jié)點的處理器將要發(fā)送的數(shù)據(jù)和自己的標(biāo)識符傳送給該節(jié)點的CAN總線接口控制器,并處于準(zhǔn)備狀態(tài);當(dāng)收到總線分配時,轉(zhuǎn)為發(fā)送報文狀態(tài)。數(shù)據(jù)根據(jù)協(xié)議組織成一定的報文格式后發(fā)出,此時網(wǎng)絡(luò)上的其他節(jié)點處于接收狀態(tài)。處于接收狀態(tài)的每個節(jié)點對接收到的報文進(jìn)行檢測,判斷這些報文是否是發(fā)給自己的以確定是否接收。
由于CAN總線是一種面向內(nèi)容的編址方案,因此很容易建立高水準(zhǔn)的控制系統(tǒng)并靈活地進(jìn)行配置我們可以很容易地在CAN總線上加進(jìn)一些新節(jié)點而無須在硬件或軟件上進(jìn)行修改。
當(dāng)提供的新節(jié)點是純數(shù)據(jù)接收設(shè)備時,數(shù)據(jù)傳輸協(xié)議不要求獨立的部分有物理目的地址。此時允許分布過程同步化。也就是說,當(dāng)總線上的控制器需要測量數(shù)據(jù)時,數(shù)據(jù)可由總線上直接獲得,而無需每個控制器都有自己獨立的傳感器。
3 CAN總線的工作特點
CAN總線的有以下三方面特點:可以多主方式工作,網(wǎng)絡(luò)上的任意節(jié)點均可以在任意時刻主動地向網(wǎng)絡(luò)上的其他節(jié)點發(fā)送信息,而不分主從,通信方式靈活。網(wǎng)絡(luò)上的節(jié)點(信息)可分成不同的優(yōu)先級,可以滿足不同的實時要求。采用非破壞性位仲裁總線結(jié)構(gòu)機(jī)制,當(dāng)兩個節(jié)點同時向網(wǎng)絡(luò)上傳送信息時,優(yōu)先級低的節(jié)點主動停止數(shù)據(jù)發(fā)送,而優(yōu)先級高的節(jié)點可不受影響地繼續(xù)傳輸數(shù)據(jù)。
4 CAN總線協(xié)議層次結(jié)構(gòu)
與前面介紹的簡單總線邏輯不同,CAN是一種復(fù)雜邏輯的總線結(jié)構(gòu)。從層次上可以將 CAN 總線劃分為三個不同層次:
(1) 物理層在物理層中定義實際信號的傳輸方法,包括位的編碼和解碼、位的定時和同步等內(nèi)容,作用是定義不同節(jié)點之間根據(jù)電氣屬性如何進(jìn)行位的實際傳輸。在物理連接上,CAN總線結(jié)構(gòu)提供兩個引腳:CANH和CANL,總線通過CANH和CANL之間的差分電壓完成信號的位傳輸。在不同系統(tǒng)中,CAN總線的位速率不同;在系統(tǒng)中,CAN總線的位速率是唯一的,并且是固定,這需要對總線中的每個節(jié)點配置統(tǒng)一的參數(shù)。
(2) 傳輸層傳輸層是CAN總線協(xié)議的核心。傳輸層負(fù)責(zé)把接收到的報文提供給對象層,以及接收來自對象層的報文。傳輸層負(fù)責(zé)位的定時及同步、報文分幀、仲裁、應(yīng)答、錯誤檢測和標(biāo)定、故障界定。
(3) 對象層在對象層中可以為遠(yuǎn)程數(shù)據(jù)請求以及數(shù)據(jù)傳輸提供服務(wù),確定由實際要使用的傳輸層接收哪一個報文,并且為恢復(fù)管理和過載通知提供手段。
5 CAN總線的報文結(jié)構(gòu)
CAN 總線上的報文傳輸由以下 4 個不同的幀類型表示和控制。
(1) 數(shù)據(jù)幀
數(shù)據(jù)幀攜帶數(shù)據(jù)從發(fā)送器至接收器。總線上傳輸?shù)拇蠖嗍沁@種幀。從標(biāo)識符長度上,又可以把數(shù)據(jù)幀分為標(biāo)準(zhǔn)幀(11 位標(biāo)識符)和擴(kuò)展幀(29 位標(biāo)識符)。
數(shù)據(jù)幀由 7 個不同的位場組成:幀起始、仲裁場、控制場、數(shù)據(jù)場、CRC場、應(yīng)答場、幀結(jié)束。其中,數(shù)據(jù)場的長度為0~8個字節(jié)。標(biāo)識符位于仲裁場中,報文接收節(jié)點通過標(biāo)識符進(jìn)行報文濾波。幀結(jié)構(gòu)如圖所示
(2) 遠(yuǎn)程幀
由總線上的節(jié)點發(fā)出,用于請求其他節(jié)點發(fā)送具有同一標(biāo)識符的數(shù)據(jù)幀。當(dāng)某個節(jié)點需要數(shù)據(jù)時,可以發(fā)送遠(yuǎn)程幀請求另一節(jié)點發(fā)送相應(yīng)數(shù)據(jù)幀。與數(shù)據(jù)幀相比,遠(yuǎn)程幀沒有數(shù)據(jù)場,結(jié)構(gòu)如圖所示。
(3) 錯誤幀
任何單元,一旦檢測到總線錯誤就發(fā)出錯誤幀。錯誤幀由兩個不同的場組成,第一個場是由不同站提供的錯誤標(biāo)志的疊加(錯誤標(biāo)志),第二個場是錯誤界定符。
(4) 過載幀
過載幀用于在先行的和后續(xù)的數(shù)據(jù)幀(或遠(yuǎn)程幀)之間提供附加延時。過載幀包括兩個場:過載標(biāo)志和過載界定符。
6 CAN接口配置
在 Linux 系統(tǒng)中,CAN總線接口設(shè)備作為網(wǎng)絡(luò)設(shè)備被系統(tǒng)進(jìn)行統(tǒng)一管理。在控制臺下,CAN總線的配置和以太網(wǎng)的配置使用相同的命令。
? ? ? 在上面的結(jié)果中,eth0 和 eth1 設(shè)備為以太網(wǎng)接口,can0 設(shè)備為 CAN 總線接口。接下來使用 ip 命 令來配置 CAN 總線的位速率:
ip link set can0 type cantq 125 prop-seg 6phase-seg1 7 phase-seg2 2 sjw 1ip link set can0 type can bitrate 500000 triple-sampling onifconfig can0 up cansend can0 145#1122334455667788candump can0當(dāng)設(shè)置完成后,可以通過下面的命令查詢 can0 設(shè)備的參數(shù)設(shè)置:
ip -details link show can07?代碼??
/*1.報文發(fā)送程序*/#include#include#include#include#include#include#include#include#includeint main(){ int s,nbytes; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame[2] = {{0}}; s = socket(PF_CAN, SOCK_RAW, CAN_RAW);//創(chuàng)建套接字 strcpy(ifr.ifr_name, "can0"); ioctl(s, SIOCGIFINDEX, &ifr);//指定can0設(shè)備 addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(s, (structsockaddr*)&addr, sizeof(addr));//將套接字與can0綁定 //禁用過濾規(guī)則,本進(jìn)程不接收報文,只負(fù)責(zé)發(fā)送 setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); //生成兩個報文 frame[0].can_id = 0x11; frame[0].can_dlc = 1; frame[0].data[0] = 'Y'; frame[0].can_id = 0x22; frame[0].can_dlc = 1; frame[0].data[0] = 'N'; //循環(huán)發(fā)送兩個報文 while(1) { nbytes = write(s,&frame[0], sizeof(frame[0]));//發(fā)送frame[0] if(nbytes! = sizeof(frame[0])) { printf("Send Error frame[0]\n!"); break;//發(fā)送錯誤,退出 } sleep(1); nbytes = write(s,&frame[1], sizeof(frame[1]));//發(fā)送frame[1] if(nbytes != sizeof(frame[0])) { printf("SendErrorframe[1]\n!"); break; } sleep(1); } close(s); return0;}/*2.報文過濾接收程序*/#include#include#include#include#include#include#include#include#includeint main(){ int s,nbytes; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; struct can_filter rfilter[1]; s = socket(PF_CAN, SOCK_RAW, CAN_RAW);//創(chuàng)建套接字 strcpy(ifr.ifr_name, "can0"); ioctl(s, SIOCGIFINDEX, &ifr);//指定can0設(shè)備 addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(s,(struct sockaddr*)&addr, sizeof(addr));//將套接字與can0綁定 //定義接收規(guī)則,只接收表示符等于0x11的報文 rfilter[0].can_id=0x11; rfilter[0].can_mask = CAN_SFF_MASK; //設(shè)置過濾規(guī)則 setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); while(1) { nbytes = read(s, &frame, sizeof(frame));//接收報文 //顯示報文 if(nbytes>0) { printf("ID=0x%XDLC=%ddata[0]=0x%X\n",frame.can_id, frame.can_dlc,frame.data[0]); } } close(s); return 0;}總結(jié)
以上是生活随笔為你收集整理的linux can总线接收数据串口打包上传_【Linux应用】CAN总线编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSP201912-3化学方程式
- 下一篇: 台式机通过网线连接笔记本上网