CAN接口应用开发

CAN设备在Linux系统中以网络设备的形式呈现,通常设备名为can[n],n为从0开发的自然数。使用ifconfig命令可以查看到系统中的CAN设备。在LInux系统中提供SocketCAN接口来方便开发者操作CAN设备。


初始化CAN设备:

int can_fd; 

can_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (can_fd < 0) {
   perror("Socket");
   return 1;
}


设置使用指定的can接口,这里选择can0设备。

struct ifreq ifr;

strcpy(ifr.ifr_name, "can0");
ioctl(s, SIOCGIFINDEX, &ifr);


绑定can接口

struct sockaddr_can addr; 

addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(s, (struct sockaddr *)&addr, sizeof(addr));



收发操作:

CAN设备收发数据是以Frame的结构,在Linux中表示如下:

struct can_frame { 
	canid_t can_id;//CAN 标识符 
	__u8 can_dlc;//数据场的长度 
	__u8 data[8];//数据 
};

发送数据:

struct can_frame frame;
int wsize;
frame.can_id = 0x123;//如果为扩展帧,那么 frame.can_id = CAN_EFF_FLAG | 0x123; 
frame.can_dlc = 1; //数据长度为 1 
frame.data[0] = 0xAB; //数据内容为 0xAB 

wsize = write(can_fd, &frame, sizeof(frame));

接收数据:

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


过滤规则:

在接收的时,可以预先设置过滤规则,实现CAN帧报文的过滤。Linux提供了can_filter结构体来实现。

struct can_filter {
	canid_t can_id;
	canid_t can_mask;
};

struct can_filter rfilter[1];
rfilter[0].can_id   = 0x550;
rfilter[0].can_mask = 0xFF0;
//rfilter[1].can_id   = 0x200;
//rfilter[1].can_mask = 0x700;

setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));