/********************************************************************************* * Copyright: (C) 2024 LingYun IoT System Studio * All rights reserved. * * Filename: can_test.c * Description: This file is socket CAN loop test program * * Version: 1.0.0(05/26/2024) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "05/26/2024 05:42:49 PM" * ********************************************************************************/ #include #include #include #include #include #include #include #include #include #include // 打印使用帮助信息 void print_usage(const char *progname) { printf("Usage: %s -i -m \n", progname); printf("Options:\n"); printf(" -i, --interface CAN interface (e.g., can0)\n"); printf(" -m, --mode Mode: send or receive\n"); printf(" -h, --help Display this help message\n"); } void send_can_message(const char *ifname) { int fd; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; // 创建socket fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (fd < 0) { perror("socket"); exit(1); } // 指定CAN接口 strcpy(ifr.ifr_name, ifname); ioctl(fd, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; // 绑定socket到CAN接口 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } // 构造CAN帧 frame.can_id = 0x123; // 设置CAN ID frame.can_dlc = 2; // 数据长度 frame.data[0] = 0x11; // 数据 frame.data[1] = 0x22; // 数据 // 发送CAN帧 if (write(fd, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) { perror("write"); exit(1); } // 关闭socket close(fd); } void receive_can_message(const char *ifname) { int fd; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; // 创建socket fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (fd < 0) { perror("socket"); exit(1); } // 指定CAN接口 strcpy(ifr.ifr_name, ifname); ioctl(fd, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; // 绑定socket到CAN接口 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } // 接收CAN帧 while (1) { int nbytes = read(fd, &frame, sizeof(struct can_frame)); if (nbytes < 0) { perror("read"); exit(1); } if (nbytes < sizeof(struct can_frame)) { fprintf(stderr, "read: incomplete CAN frame\n"); exit(1); } // 打印接收到的CAN帧 printf("Received CAN frame: ID=0x%X DLC=%d data=", frame.can_id, frame.can_dlc); for (int i = 0; i < frame.can_dlc; i++) printf("%02X ", frame.data[i]); printf("\n"); } // 关闭socket close(fd); } int main(int argc, char **argv) { int opt, index = 0; const char *ifname = NULL; const char *mode = NULL; // 定义长选项 static struct option long_options[] = { {"interface", required_argument, 0, 'i'}, {"mode", required_argument, 0, 'm'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; while ((opt = getopt_long(argc, argv, "i:m:h", long_options, &index)) != -1) { switch (opt) { case 'i': ifname = optarg; break; case 'm': mode = optarg; break; case 'h': print_usage(argv[0]); return 0; default: print_usage(argv[0]); return 1; } } if (ifname == NULL || mode == NULL) { print_usage(argv[0]); return 1; } if (strcmp(mode, "send") == 0) { send_can_message(ifname); } else if (strcmp(mode, "receive") == 0) { receive_can_message(ifname); } else { fprintf(stderr, "Invalid mode: %s\n", mode); print_usage(argv[0]); return 1; } return 0; }