[英]SocketCAN read from socket only returns 11cobid
I am trying to read from a socketCAN and the msg is always filtered for the 11bit identifier.我正在尝试从 socketCAN 中读取,并且总是针对 11 位标识符过滤 msg。 This should be a problem fixable with setting the rpoper flags for the 29bit identifier but I can`t find where if anyone can help...
这应该是一个可以通过为 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;
I am sending a CAN frame with idx x901 and this is what is printed:我正在发送一个带有 idx x901 的 CAN 帧,这是打印的内容:
READ COB_ID:80000101读取 COB_ID:80000101
READ COB_ID:80000101读取 COB_ID:80000101
READ COB_ID:80000101读取 COB_ID:80000101
I have troubleshooted this in many different ways and it seems that the C code is working as it should, but I suspect the problem to be with the kernel module for either mcp251x which is not correctly receiving the extended flag?我已经用许多不同的方式解决了这个问题,似乎 C 代码正在正常工作,但我怀疑问题出在没有正确接收扩展标志的 mcp251x 的内核模块上? Or it may be with some initialization I need to do before running the kernel module???
或者它可能是在运行内核模块之前我需要做的一些初始化???
Thank you in advance to anyone who can help.预先感谢任何可以提供帮助的人。
Your understanding of CAN flags and filtering is not correct.您对 CAN 标志和过滤的理解不正确。 Take a look at extract from linux can.h:
看看 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 */
Here is an example that works for both SFF and EFF messages:这是一个适用于 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;
}
Now sending these messages:现在发送这些消息:
cansend vcan0 00000123#FFFFFFFFFFFFFFFF
cansend vcan0 12345678#FFFFFFFFFFFFFFFF
gives correct output:给出正确的输出:
READ COB_ID: 123
READ COB_ID: 12345678
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.