不清楚为什么十六进制值的第一位显示为自身的 +8 版本。接口CAN
Unclear as to why first digit of hex value is appearing as a +8 version of itself. SocketCAN
任务
我想写我自己的 candump 的小版本。目的是它本质上相似,但唯一的特点是我只想显示来自一个 CAN ID 的传入消息。
代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int
main(void) {
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
// struct can_filter *rfilter; // how do work?
const char *ifname = "vcan0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
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");
return -2;
}
nbytes = read(s, &frame, sizeof(struct can_frame));
if(nbytes < 0) {
perror("Error reading from socket.\n");
return 1;
}
while(1) {
if(read(s, &frame, sizeof(struct can_frame)) > 0) {
//printf("Message...\n");
printf("%X - [len] - %X %X %X %X %X %X %X %X\n", frame.can_id,
frame.data[0], frame.data[1], frame.data[2], frame.data[3],
frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
}
}
close(s);
return 0;
}
问题
我一直在使用 cansend 命令 cansend vcan0 18DA40F1#1234
。当 运行 我的代码时,我得到的响应几乎就在那里,除了 CAN ID 中的第一个字符是一个大 8+ 的值。响应 98DA40F1 - [len] - 12 34 0 0 0 0 0 0
我取回 运行 我的代码。
查看前面提到的 candump 的源代码,我认为它与 rfilter
有关,但我不是 100% 确定并检查了 SocketCAN 文档,感觉并没有更清楚.跟屏蔽有关系吗?如何解决我的问题的示例将不胜感激。如果您觉得我没有提到任何内容,请随时提问。
来自 SocketCAN - The official CAN API of the Linux kernel 第 05-21 页:
“can_id” is 32 bit wide, holding the CAN id in
the lower 11 bit. An extended CAN id is
indicated by a set “CAN_EFF_FLAG” flag, the CAN id then covers the lower 29 bits. An
RTR frame is signaled by the
“CAN_RTR_FLAG” flag. “can_dlc” defines
the number of used data bytes in the CAN
frame, The payload of 8 bytes is located in
the “data” array.
所以98DA40F1的29-LSB就是18DA40F1。 CAN_EFF_FLAG
和CAN_RTR_FLAG
的值分别是0x80000000U和0x20000000U。在您的情况下,CAN_EFF_FLAG
设置为指示 29 nit 扩展 ID。
printf("%X - [len] - %X %X %X %X %X %X %X %X\n",
frame.can_id & 0x1fffffffu, // 29 bit CAN ID
frame.data[0], frame.data[1], frame.data[2], frame.data[3],
frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
任务
我想写我自己的 candump 的小版本。目的是它本质上相似,但唯一的特点是我只想显示来自一个 CAN ID 的传入消息。
代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int
main(void) {
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
// struct can_filter *rfilter; // how do work?
const char *ifname = "vcan0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
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");
return -2;
}
nbytes = read(s, &frame, sizeof(struct can_frame));
if(nbytes < 0) {
perror("Error reading from socket.\n");
return 1;
}
while(1) {
if(read(s, &frame, sizeof(struct can_frame)) > 0) {
//printf("Message...\n");
printf("%X - [len] - %X %X %X %X %X %X %X %X\n", frame.can_id,
frame.data[0], frame.data[1], frame.data[2], frame.data[3],
frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
}
}
close(s);
return 0;
}
问题
我一直在使用 cansend 命令 cansend vcan0 18DA40F1#1234
。当 运行 我的代码时,我得到的响应几乎就在那里,除了 CAN ID 中的第一个字符是一个大 8+ 的值。响应 98DA40F1 - [len] - 12 34 0 0 0 0 0 0
我取回 运行 我的代码。
查看前面提到的 candump 的源代码,我认为它与 rfilter
有关,但我不是 100% 确定并检查了 SocketCAN 文档,感觉并没有更清楚.跟屏蔽有关系吗?如何解决我的问题的示例将不胜感激。如果您觉得我没有提到任何内容,请随时提问。
来自 SocketCAN - The official CAN API of the Linux kernel 第 05-21 页:
“can_id” is 32 bit wide, holding the CAN id in the lower 11 bit. An extended CAN id is indicated by a set “CAN_EFF_FLAG” flag, the CAN id then covers the lower 29 bits. An RTR frame is signaled by the “CAN_RTR_FLAG” flag. “can_dlc” defines the number of used data bytes in the CAN frame, The payload of 8 bytes is located in the “data” array.
所以98DA40F1的29-LSB就是18DA40F1。 CAN_EFF_FLAG
和CAN_RTR_FLAG
的值分别是0x80000000U和0x20000000U。在您的情况下,CAN_EFF_FLAG
设置为指示 29 nit 扩展 ID。
printf("%X - [len] - %X %X %X %X %X %X %X %X\n",
frame.can_id & 0x1fffffffu, // 29 bit CAN ID
frame.data[0], frame.data[1], frame.data[2], frame.data[3],
frame.data[4], frame.data[5], frame.data[6], frame.data[7]);