SocketCAN:read() 函数从不 returns

SocketCAN: read() function never returns

我正在开发自定义嵌入式 Linux 系统,该系统需要在 CAN 总线上读取和写入消息。 SocketCAN 正被用来完成这个。

CAN 接口 can0 在启动时启动,波特率设置为 500 kbps。我正在使用 CANoe、cangen 和 candump 来测试消息的接收和传输。当CANoe设置为向嵌入式系统发送消息时,candump在嵌入式系统上读取这些消息是没有问题的。当cangen设置为发送消息时,CANoe从嵌入式系统读取消息没有问题。

我编写了一个小程序,使用 read() 函数从 can0 接口读取消息。当调用 read() 函数来读取单个 CAN 消息时,该函数会阻塞,然后永远不会 returns。我确定 CAN 接口正在接收数据,因为 ifconfig 报告的接收字节数按预期增加。 运行 candump 与我的程序并发还显示接口正在从总线接收 CAN 消息。下面是打开和读取CAN接口的相关代码。省略了错误检查。

打开套接字:

int socketNum = 0;
char interface[10] = "can0";
struct sockaddr_can addr;
struct ifreq ifr;

memset(&addr, 0, sizeof(addr));
memset(&ifr, 0, sizeof(ifr));

socketNum = socket(PF_CAN, SOCK_RAW, CAN_RAW);

addr.can_family = AF_CAN;

strncpy(ifr.ifr_name, interface, sizeof(interface));
ioctl(socketNum, SIOCGIFINDEX, &ifr);

addr.can_ifindex = ifr.ifr_ifindex;

bind(socketNum, (struct sockaddr *)&addr, sizeof(addr));

读取套接字:

struct can_frame frame;
int nbytes = 0;

memset(&frame, 0, sizeof(frame));

/* Never returns despite interface receiving messages */
nbytes = read(socketNum, &frame, sizeof(frame));

我是不是在我的代码中遗漏了什么或者做错了什么?有没有其他人遇到过这个问题并找到了解决方案?

我找到了解决问题的方法。

我正在开发的嵌入式平台为 FLEXCAN IP 使用 IMX 8 和 NXP 驱动程序。我的设备树是使用 disable-fd-mode 选项设置的。尽管应该禁用 FD 模式,但我需要使用 setsockopt "enable" FD 模式:

canfd_enabled = 1;
error_code = setsockopt(socketNum, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_enabled, sizeof(int));

添加这些代码行后,我可以按预期从套接字读取和写入。我还读取和写入了 sizeof(canfd_frame) 字节而不是 sizeof(can_frame) 字节。 FLEXCAN 驱动程序可能有问题。根据我的经验,这对于 NXP 驱动程序来说并不罕见。

我也有这个问题,使用 Colibri iMX6

对我有用的代码行是:

int canfd_enabled = 1;
int error_code;

error_code = setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_enabled, sizeof(int));

nbytes = read(s, &frame, sizeof(struct can_frame));

谢谢 Dschumanji!