Linux CAN数据收发

在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;  
}
 

相关推荐

  1. Linux CAN数据收发

    2024-07-20 20:52:01       16 阅读
  2. STM32xx系列单片机串口数据收发

    2024-07-20 20:52:01       29 阅读
  3. 机器学习流程—数据收集

    2024-07-20 20:52:01       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 20:52:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 20:52:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 20:52:01       45 阅读
  4. Python语言-面向对象

    2024-07-20 20:52:01       55 阅读

热门阅读

  1. shell + Python3 | 解析理解 gencode gtf 基因组注释文件

    2024-07-20 20:52:01       14 阅读
  2. dockerfile

    2024-07-20 20:52:01       16 阅读
  3. 一周速递|全球车联网产业动态(2024年7月21日)

    2024-07-20 20:52:01       17 阅读
  4. 好文推荐与一句话的答案

    2024-07-20 20:52:01       17 阅读
  5. 【玩转python】入门篇day11-位运算

    2024-07-20 20:52:01       17 阅读
  6. SpringBoot接入JPA连接数据库H2或MySQL例子

    2024-07-20 20:52:01       14 阅读
  7. CentOS7中的yum命令不可用,网络不可达

    2024-07-20 20:52:01       14 阅读