<aside> 💡 其實跟 TCP/IP 的方式蠻像的
</aside>
struct canfd_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 len; /* frame payload length in byte (0 .. 64) */
__u8 flags; /* additional flags for CAN FD */
__u8 __res0; /* reserved / padding */
__u8 __res1; /* reserved / padding */
__u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
};
typedef __u32 canid_t;
typedef unsigned int __u32;
typedef unsigned char __u8;
#define CANFD_MAX_DLEN 64
/------------------------/
#define CANFD_MTU (sizeof(struct canfd_frame)) == 72 //canfd_frame
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/ioctl.h>
#include <net/if.h>
int main() {
int s;
struct sockaddr_can addr;
struct canfd_frame frame;
struct ifreq ifr;
const char *ifname = "vcan0"; //設置CAN名稱
//創建socket
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Socket creation error");
return -1;
}
strcpy(ifr.ifr_name, ifname);
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
perror("SIOCGIFINDEX");
return 1;
}
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
int enable_canfd = 1; //open FD mode
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd)) < 0) {
perror("CAN FD support error");
return -1;
}
//綁定
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Binding error");
return -1;
}
frame.can_id = 0x123; //dec:291
frame.len = 8;
frame.flags = CANFD_BRS | CANFD_ESI;
char mes; //upper[256]
while(scanf("%s", &mes)){
strcpy(frame.data, &mes);
if (write(s, &frame, sizeof(frame)) != sizeof(frame)) {
perror("Write error");
return -1;
}
}
close(s);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/ioctl.h>
int main() {
int s;
struct sockaddr_can addr;
struct canfd_frame frame;
struct ifreq ifr;
const char *ifname = "vcan0"; //設置CAN名稱
//創建socket
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Socket creation error");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
int enable_canfd = 1; //open FD mode
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd)) < 0) {
perror("CAN FD support error");
return -1;
}
//綁定
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Binding error");
return -1;
}
//接收
while (1) {
if (read(s, &frame, sizeof(frame)) > 0) {
printf("can_id : %x\\n", frame.can_id); //4 byte
printf("len : %d\\n", frame.len); //1 byte
printf("flag : %d\\n", frame.flags); //1 byte
//printf("%d\\n", sizeof(frame.__res0)); //1 byte
//printf("%d\\n", sizeof(frame.__res1)); //1 byte
//printf("%d\\n", sizeof(frame.data)); //64 byte
//printf("%d\\n", CANFD_MTU); //#define CANFD_MTU (sizeof(struct canfd_frame)) == 72 => CAN FD frame
for (int i = 0; i < frame.len; i++) {
printf("Data[%d]: %02X\\n", i, frame.data[i]);
}
printf("----------\\n"); //
}
}
close(s);
return 0;
}