SocketCAN:read()函数永远不会返回



我正在开发一个定制的嵌入式Linux系统,该系统需要在CAN总线上读写消息。SocketCAN正被用来实现这一点。

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

我编写了一个小程序,使用read((函数从can0接口读取消息。当调用read((函数读取单个CAN消息时,该函数会阻塞,然后再也不会返回。我确信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));

我是在代码中遗漏了什么还是做错了什么?是否有其他人遇到此问题并找到解决方案?

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

我正在开发的嵌入式平台使用IMX 8和用于FLEXCAN IP的NXP驱动程序。我的设备树是用禁用fd模式选项设置的。即使FD模式应该被禁用,我也需要用setstockopt:"启用"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驱动程序可能有问题。根据我的经验,这对于恩智浦的驱动程序来说并不罕见。

我也遇到了这个问题,使用了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!

最新更新