c - 不清楚为什么十六进制值的第一个数字显示为自身的 +8 版本.插座罐



Task

我想写我自己的小版本的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 %Xn", 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 - Linux 内核 p.05-21 的官方 CAN API:

"can_id"为32位宽,将CANID保留在 较低的 11 位。扩展的 CAN ID 是 由一组"CAN_EFF_FLAG"标志指示,然后CANID覆盖较低的29位。一 RTR 帧由 "CAN_RTR_FLAG"标志。"can_dlc"定义 CAN中使用的数据字节数 帧,8 字节的有效载荷位于 "数据"数组。

所以98DA40F1

的29-LSB是18DA40F1。 CAN_EFF_FLAGCAN_RTR_FLAG 的值分别为 0x80000000U 和 0x20000000U。在您的情况下,CAN_EFF_FLAG设置指示 29 尼特扩展 ID。

        printf("%X - [len] - %X %X %X %X %X %X %X %Xn", 
               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]);

最新更新