日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

bbb SOCKET CAN

發布時間:2023/12/13 综合教程 38 生活家
生活随笔 收集整理的這篇文章主要介紹了 bbb SOCKET CAN 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

系統將CAN設備作為網絡設備進行管理,因此在CAN總線應用開發方面,Linux提供了SocketCAN接口,使得CAN總線通信近似于和以太網的通信,應用程序開發接口更加通用,也更加靈活。

我們使用原始套接字與BBB的can綁定,進行通信。

1. 初始化

SocketCAN中大部分的數據結構和函數在頭文件linux/can.h 中進行了定義。CAN總線套接字的創建采用標準的網絡套接字操作來完成。網絡套接字在頭文件sys/socket.h中定義。套接字的初始化方法如下:

int s;  
struct sockaddr_can addr;  
struct ifreq ifr;  
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);   //創建SocketCAN套接字  
strcpy(ifr.ifr_name, "can0" );  
ioctl(s, SIOCGIFINDEX, &ifr);      //指定can0設備  
addr.can_family = AF_CAN;  
addr.can_ifindex = ifr.ifr_ifindex;  
bind(s, (struct sockaddr *)&addr, sizeof(addr));   //將套接字與can0綁定

2. 數據發送

在數據收發的內容方面,CAN總線與標準套接字通信稍有不同,每一次通信都采用can_ frame結構體將數據封裝成幀。結構體定義如下:

struct can_frame {  
        canid_t can_id;      //CAN標識符  
        __u8  can_dlc;     //數據場的長度  
        __u8  data[8];     //數據  
}; 

can_id為幀的標識符,如果發出的是標準幀,就使用can_id的低11位;如果為擴展幀,就使用0~28位。can_id的第29、30、31位是幀的標志位,用來定義幀的類型,定義如下:

#define CAN_EFF_FLAG 0x80000000U    //擴展幀的標識  
#define CAN_RTR_FLAG 0x40000000U    //遠程幀的標識  
#define CAN_ERR_FLAG 0x20000000U    //錯誤幀的標識,用于錯誤檢查 

數據發送使用write函數來實現。如果發送的數據幀(標識符為0x123)包含單個字節(0xAB)的數據,可采用如下方法進行發送:

struct can_frame frame;  
frame.can_id = 0x123;      //如果為擴展幀,那么frame.can_id = CAN_EFF_FLAG | 0x123;  
frame.can_dlc = 1;     //數據長度為1  
frame.data[0] = 0xAB;     //數據內容為0xAB  
int nbytes = write(s, &frame, sizeof(frame)); //發送數據  
if (nbytes != sizeof(frame))   //如果nbytes不等于幀長度,就說明發送失敗  
  printf("Error
!"); 

如果要發送遠程幀(標識符為0x123),可采用如下方法進行發送:

struct can_frame frame;  
frame.can_id = CAN_RTR_FLAG | 0x123;  
write(s, &frame, sizeof(frame)); 

3. 數據接收

數據接收使用read函數來完成,實現如下:

struct can_frame frame;  
int nbytes = read(s, &frame, sizeof(frame)); 

當然,套接字數據收發時常用的send、sendto、sendmsg以及對應的recv函數也都可以用于CAN總線數據的收發。

4. 錯誤處理

當幀接收后,可以通過判斷can_id中的CAN_ERR_FLAG位來判斷接收的幀是否為錯誤幀。如果為錯誤幀,可以通過can_id的其他符號位來判斷錯誤的具體原因。

錯誤幀的符號位在頭文件linux/can/error.h中定義。

5. 過濾規則設置

在數據接收時,系統可以根據預先設置的過濾規則,實現對報文的過濾。過濾規則使用can_filter結構體來實現,定義如下:

struct can_filter {  
canid_t can_id;  
canid_t can_mask;  
}; 

過濾的規則為:

接收到的數據幀的can_id&mask==can_id&mask

通過這條規則可以在系統中過濾掉所有不符合規則的報文,使得應用程序不需要對無關的報文進行處理。在can_filter結構的can_id中,符號位CAN_INV_FILTER在置位時可以實現can_id在執行過濾前的位反轉。

用戶可以為每個打開的套接字設置多條獨立的過濾規則,使用方法如下:

structcan_filterrfilter[2];
rfilter[0].can_id=0x123;
rfilter[0].can_mask=CAN_SFF_MASK;//#defineCAN_SFF_MASK0x000007FFU
rfilter[1].can_id=0x200;
rfilter[1].can_mask=0x700;
setsockopt(s,SOL_CAN_RAW,CAN_RAW_FILTER,&rfilter,sizeof(rfilter));//設置規則

在極端情況下,如果應用程序不需要接收報文,可以禁用過濾規則。這樣的話,原始套接字就會忽略所有接收到的報文。在這種僅僅發送數據的應用中,可以在內核中省略接收隊列,以此減少CPU資源的消耗。禁用方法如下:

setsockopt(s,SOL_CAN_RAW,CAN_RAW_FILTER,NULL,0);//禁用過濾規則

通過錯誤掩碼可以實現對錯誤幀的過濾,例如:

can_err_mask_terr_mask=(CAN_ERR_TX_TIMEOUT|CAN_ERR_BUSOFF);
setsockopt(s,SOL_CAN_RAW,CAN_RAW_ERR_FILTER,err_mask,sizeof(err_mask));

在默認情況下,本地回環功能是開啟的,可以使用下面的方法關閉回環/開啟功能:

intloopback=0;//0表示關閉,1表示開啟(默認)
setsockopt(s,SOL_CAN_RAW,CAN_RAW_LOOPBACK,&loopback,sizeof(loopback));

在本地回環功能開啟的情況下,所有的發送幀都會被回環到與CAN總線接口對應的套接字上。默認情況下,發送CAN報文的套接字不想接收自己發送的報文,因此發送套接字上的回環功能是關閉的??梢栽谛枰臅r候改變這一默認行為:

intro=1;//0表示關閉(默認),1表示開啟
setsockopt(s,SOL_CAN_RAW,CAN_RAW_RECV_OWN_MSGS,&ro,sizeof(ro));

總結

以上是生活随笔為你收集整理的bbb SOCKET CAN的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。