can-utilsのソースコードを解析した結果、
標準フレームの送信をする処理を起こしました。
動作環境は、OS:raspbian jessie です。
CANデバイスは、まだCANモジュールが来ていないので、
以下のコマンドで作った仮想CANデバイス(vcan1)で送信します。
sudo modprobe vcan sudo ip link add dev vcan1 type vcan sudo ip link set vcan1 up
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <linux/can.h> #include <linux/can/raw.h> #define CAN_NAME "vcan1" int cansend_stdframe(unsigned short id, unsigned char dlc, unsigned char data[]) { int s; struct ifreq ifr; struct sockaddr_can addr; struct can_frame frame; int loopback; if(CAN_MAX_DLEN < dlc) { fprintf(stderr, "dlc too long.\n"); return -1; } memset(&frame, 0, sizeof(frame)); frame.can_id = id; frame.can_dlc = dlc; memcpy(&(frame.data[0]), &(data[0]), dlc); if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("socket"); return -2; } memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, CAN_NAME, sizeof(ifr.ifr_name)); ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name); if(! ifr.ifr_ifindex) { perror("if_nametoindex"); return -3; } addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); /* no loopback */ loopback = 0; /* 0 = disabled, 1 = enabled(default) */ setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback)); if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return -4; } if(write(s, &frame, CAN_MTU) < CAN_MTU) { perror("write"); return -5; } close(s); return 0; } int main(int argc, char argv[]) { unsigned char data[] = { 0x11, 0x22, 0x33, 0x44 }; cansend_stdframe(0x0123, sizeof(data), data); }
ループバックをoffにしているので、candumpで見ていても、何も出てきません。
loopbackの値を1にすれば、出てくるようになります。
CAN標準フレームの送信に必要な処理は、これでわかりました。
次は、これをpythonで実装します。
0 件のコメント:
コメントを投稿