使用CAN本人归纳为6个步骤:
0.测试之前最好先下载安装好测试工具can-utils
sudo apt-get install can-utils
1.加载can设备驱动:
2.设置波特率(注意这里不能使能can或者打开can)
sudo ip link set can0 type can bitrate 500000 dbitrate 2000000 berr-reporting on fd on sudo ip link set can1 type can bitrate 500000 dbitrate 2000000 berr-reporting on fd on
如果出现了RTNETLINK answers: Device or resource busy 这种情况,则需要使用命令
sudo ip link set down can0 sudo ip link set down can1
来关闭掉;
3.设置为回环模式(因为要测试使用,在不外接can驱动和120欧姆电阻的情况下是可以回环测试的,使用can0设备)
sudo ip link set can0 type can loopback on
如果由外设,可以省略此步骤。
4.开启can设备:
5.发送和接收:
发送:
cansend can0 123#abcdabcd
cansend是命令,can0是参数,123是ID,#分隔符,abcdabcd是发送数据。
接收:接收需要另外开一个终端
candump can0
candump 是命令,can0是参数,表示哪个设备,这个命令是阻塞型的,会一直等待接收。
6.关闭can设备。
sudo ip link set down can0 sudo ip link set down can1
上面的测试,本人是在tx2上面一会儿就跑通了。但是不满足控制出身的技术人员对于控制的需要,所以需要自己写一个程序来实现接收和发送。使用了实例程序:
两个c文件:1.can_send.c
#include <linux/can/raw.h> struct sockaddr_can addr; struct can_frame frame[2]={{0}}; s=socket(PF_CAN,SOCK_RAW,CAN_RAW); strcpy(ifr.ifr_name,"can0"); ioctl(s,SIOCGIFINDEX,&ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(s,(struct sockaddr*)&addr,sizeof(addr)); setsockopt(s,SOL_CAN_RAW,CAN_RAW_FILTER,NULL,0); frame[1].can_id = 0x11;//0x33; nbytes = write(s, &frame[0], sizeof(frame[0])); printf("nbytes=%d\n",nbytes); if(nbytes != sizeof(frame[0])) printf("Send Error frame[0]\n!"); nbytes = write(s, &frame[1], sizeof(frame[1])); if(nbytes != sizeof(frame[1])) printf("Send Error frame[1]\n!");
2.can_receive.c
#include <linux/can/raw.h> struct sockaddr_can addr; struct can_filter rfilter[1]; s = socket(PF_CAN, SOCK_RAW, CAN_RAW); //创建套接字 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 绑定 //定义接收规则,只接收表示符等于 0x11 的报文 rfilter[0].can_id = 0x11; rfilter[0].can_mask = CAN_SFF_MASK; setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); nbytes = read(s, &frame, sizeof(frame)); printf("ID=0x%X DLC=%d data[0]=0x%X\n",frame.can_id,frame.can_dlc,frame.data[0]); //printf(“ID=0x%X DLC=%d data[0]=0x%X\n”, frame.can_id, frame.can_dlc, frame.data[0]);
实测也是可以实现发送与接收的。
|