由于没有can通信设备,使用以下命令模拟了一个vcan0接口
编写程序,首先向vcan0发送两次数据,之后监听数据
代码:
extern "C" {
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
}
#include <string>
using namespace std;
int main(){
int socket_0;
struct sockaddr_can addr_0;
struct ifreq ifr;//接口请求结构体
struct can_frame frame;
socket_0 = ::socket(PF_CAN,SOCK_RAW,CAN_RAW);//创建套接字
strcpy((char *)(ifr.ifr_name),"vcan0");
//fcntl(socket, F_SETFL, 1); //标志FNDELAY可以保证read函数在端口上读不到字符的时候返回0
fcntl(socket_0, F_SETFL, 0); //回到正常(阻塞)模式
ioctl(socket_0,SIOCGIFINDEX,&ifr);//指定 CAN0/1 设备
addr_0.can_family = AF_CAN;//协议类型
addr_0.can_ifindex = ifr.ifr_ifindex;//can总线外设的具体索引 类似 ip地址
bind(socket_0,(struct sockaddr*)&addr_0,sizeof(addr_0));//将套接字和canbus外设进行绑定,即套接字与 can0/1 绑定
memset(&frame,0,sizeof(struct can_frame));
frame.can_id = (0x12345678 & CAN_EFF_MASK) | CAN_EFF_FLAG;//扩展帧
//frame.can_id = (0x12345678 & CAN_SFF_MASK);//标准帧
frame.can_dlc= 8;
frame.data[0]= 0x11;
frame.data[1]= 0x22;
frame.data[2]= 0x33;
frame.data[3]= 0x44;
frame.data[4]= 0xaa;
frame.data[5]= 0xbb;
frame.data[6]= 0xcc;
frame.data[7]= 0xdd;
//发送can数据:方式一
sendto(socket_0,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr_0,sizeof(addr_0));
//发送can数据:方式二
//write(socket_0, &frame, sizeof(frame)); //发送 frame
frame.data[0]= 0xff;
frame.data[1]= 0xee;
frame.data[2]= 0xdd;
frame.data[3]= 0xcc;
frame.data[4]= 0xbb;
frame.data[5]= 0xaa;
frame.data[6]= 0x99;
frame.data[7]= 0x88;
sendto(socket_0,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr_0,sizeof(addr_0));
//接收can数据
while(1){
int nbytes;
struct can_frame frameReceive;
string data;
char dataBuffer[1024];
nbytes = read(socket_0, &frameReceive, sizeof(frameReceive)); //接收报文
if(nbytes > 0){
printf("%08X ",frameReceive.can_id&0x7fffffff);
for(int i=0;i<frameReceive.can_dlc;i++){
memset(dataBuffer,0,sizeof(dataBuffer));
sprintf(dataBuffer,"%02X",frameReceive.data[i]);
data.append(dataBuffer);
}
printf("%s\n",data.c_str());
}
}
::close(socket_0);
return 0;
}
使用can-utils对通信进行测试
安装can-utils
使用以下命令向vcan0发送十六进制数据12 34 56 78,can id:0x123
使用以下命令监听vcan0接口
效果
