SocketCAN read from socket only返回11cobid

SocketCAN read from socket only返回11cobid,c,linux,can-bus,socketcan,legato,C,Linux,Can Bus,Socketcan,Legato,我试图从socketCAN读取消息,消息总是被过滤为11位标识符。 设置29位标识符的rpoper标志应该可以解决这一问题,但我找不到任何人可以提供帮助的地方 struct can_frame message; struct sockaddr_can addr; struct ifreq ifr; int fd = -1; // file descriptor (it´s a socket) if((fd = so

我试图从socketCAN读取消息,消息总是被过滤为11位标识符。 设置29位标识符的rpoper标志应该可以解决这一问题,但我找不到任何人可以提供帮助的地方

    struct can_frame message;
    struct sockaddr_can addr;
    struct ifreq ifr;
    int   fd = -1;                  // file descriptor (it´s a socket)

    if((fd = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
    {
        LE_INFO("cannot open socket");
        return;
    }
    strcpy(ifr.ifr_name, "can0");
    ioctl(fd, SIOCGIFINDEX, &ifr);
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        printf("cannot bind socket\n");
        return;
    }

    uint8_t nbytes;

    message.can_id |= CAN_EFF_FLAG;

    while(1)
    {
        nbytes = read(fd, &message, sizeof(struct can_frame));

        if (nbytes < 0) {
                perror("can raw socket read");
                return;
        }

        /* paranoid check ... */
        if (nbytes < sizeof(struct can_frame)) {
                fprintf(stderr, "read: incomplete CAN frame\n");
                return;
        }

        printf("READ COB_ID:%x\n",message.can_id | CAN_EFF_FLAG);
        
    }
    return;
struct可以帧消息;
结构sockaddr\u can addr;
结构ifreq-ifr;
int fd=-1;//文件描述符(它是一个套接字)
如果((fd=插座(PF_CAN、SOCK_RAW、CAN_RAW))<0)
{
LE_信息(“无法打开插座”);
返回;
}
strcpy(ifr.ifr_名称,“can0”);
ioctl(fd、SIOCGIFINDEX和ifr);
addr.can_family=AF_can;
addr.can_iIndex=ifr.ifr_iIndex;
if(bind(fd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
printf(“无法绑定套接字\n”);
返回;
}
单位8字节;
message.can_id |=can_EFF_标志;
而(1)
{
nbytes=读取(fd,&消息,sizeof(struct can_frame));
如果(n字节<0){
perror(“可读取原始套接字”);
返回;
}
/*偏执狂检查*/
if(n字节
我正在发送一个带有idx x901的CAN帧,打印内容如下:

读取COB_ID:80000101

读取COB_ID:80000101

读取COB_ID:80000101

我已经用许多不同的方法解决了这个问题,看起来C代码工作正常,但我怀疑问题出在mcp251x的内核模块上,它没有正确地接收扩展标志?或者在运行内核模块之前需要进行一些初始化


提前感谢所有能够提供帮助的人。

您对can标志和过滤的理解不正确。看一看linux can.h的摘录:

/* special address description flags for the CAN_ID */
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */

/* valid bits in CAN ID for frame formats */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
下面是一个同时适用于SFF和EFF消息的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include <linux/can.h>
#include <linux/can/raw.h>

int main(int argc, char **argv)
{
    struct can_frame message;
    struct sockaddr_can addr;
    struct ifreq ifr;
    int   fd = -1;                  // file descriptor (it´s a socket)

    if((fd = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
    {
        printf("cannot open socket");
        return -9;
    }
    strcpy(ifr.ifr_name, "vcan0");
    ioctl(fd, SIOCGIFINDEX, &ifr);
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        printf("cannot bind socket\n");
        return -1;
    }

    u_int8_t nbytes;

    message.can_id |= CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK;

    while(1)
    {
        nbytes = read(fd, &message, sizeof(struct can_frame));

        if (nbytes < 0) {
                perror("can raw socket read");
                return -2;
        }

        /* paranoid check ... */
        if (nbytes < sizeof(struct can_frame)) {
                fprintf(stderr, "read: incomplete CAN frame\n");
                return -3;
        }

        printf("READ COB_ID: %x\n", message.can_id & CAN_EFF_MASK);

    }

    return 0;
}
cansend vcan0 00000123#FFFFFFFFFFFFFFFF
cansend vcan0 12345678#FFFFFFFFFFFFFFFF
提供正确的输出:

READ COB_ID: 123
READ COB_ID: 12345678
if(nbytes