在Linux环境下,使用SocketCAN进行CAN消息的发送和接收通常涉及到socket编程。
写了一个简单的示例,展示了如何实现CAN消息的发送(tx)和接收(rx)函数。
1. 包含必要的头文件
#include <stdio.h>  
 #include <stdlib.h>  
 #include <string.h>  
 #include <unistd.h>  
 #include <sys/types.h>  
 #include <sys/socket.h>  
 #include <net/if.h>  
 #include <sys/ioctl.h>  
 #include <linux/can.h>  
 #include <linux/can/raw.h>
 2. 定义CAN发送函数
 
 int send_can_frame(int s, struct can_frame *frame, const char *interface) {  
     struct ifreq ifr;  
     strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);  
     ifr.ifr_name[IFNAMSIZ-1] = 0;  
  
     if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {  
         perror("ioctl SIOCGIFINDEX failed");  
         return -1;  
     }  
  
     // 通常这里不需要设置ifr,因为我们在bind时已经设置了ifindex  
     // 但如果需要,可以修改frame的can_id以包含接口索引(通常不需要)  
  
     if (write(s, frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {  
         perror("Error writing on CAN socket");  
         return -1;  
     }  
  
     return 0;  
 }
 3. 定义CAN接收函数
 
 int receive_can_frame(int s, struct can_frame *frame) {  
     ssize_t numBytes;  
  
     numBytes = read(s, frame, sizeof(struct can_frame));  
     if (numBytes < 0) {  
         perror("Error reading from CAN socket");  
         return -1;  
     }  
  
     if (numBytes != sizeof(struct can_frame)) {  
         fprintf(stderr, "Incomplete CAN frame received\n");  
         return -1;  
     }  
  
     return 0;  
 }
 4. 主函数示例
 
 int main() {  
     int s;  
     struct sockaddr_can addr;  
     struct ifreq ifr;  
     struct can_frame frame, rx_frame;  
     const char *interface = "can0";  
  
     // 创建socket  
     if ((s = socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {  
         perror("Error while opening socket");  
         return 1;  
     }  
  
     // 绑定socket到CAN接口  
     strcpy(ifr.ifr_name, interface);  
     ioctl(s, SIOCGIFINDEX, &ifr);  
  
     memset(&addr, 0, sizeof(addr));  
     addr.can_family = AF_CAN;  
     addr.can_ifindex = ifr.ifr_ifindex;  
  
     if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {  
         perror("Error in socket bind");  
         close(s);  
         return 1;  
     }  
  
     // 设置要发送的CAN帧  
     frame.can_id = 0x123; // CAN ID  
     frame.can_dlc = 8;    // 数据长度  
     memset(frame.data, 0, sizeof(frame.data));  
     frame.data[0] = 0x11;  
     frame.data[1] = 0x22;  
     // ... 填充其他数据  
  
     // 发送CAN帧  
     if (send_can_frame(s, &frame, interface) < 0) {  
         close(s);  
         return 1;  
     }  
  
     // 接收CAN帧  
     if (receive_can_frame(s, &rx_frame) < 0) {  
         close(s);  
         return 1;  
     }  
  
     printf("Received CAN frame with ID 0x%X\n", rx_frame.can_id);  
  
     // 关闭socket  
     close(s);  
     return 0;  
 }