You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SocketCAN接收29位扩展帧ID与DLC正常但数据全为0问题咨询

问题根因与解决方案

代码层面错误

  • 全局struct can_frame变量污染问题
    你所有逻辑共用同一个全局frame变量,bind之后的初始化语句frame.can_id |= CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK;会将初始can_id设为0xDFFFFFFF,如果read操作异常未覆盖结构体内容,就会出现你打印的frame.can_id为0xDFFFFFFF的异常输出。
    建议:收发逻辑分别使用独立的局部结构体变量,避免互相干扰。
  • 扩展帧过滤规则配置缺失/错误
    你提到已配置29位标识符过滤,但贴出的代码中未包含setsockopt配置CAN_RAW_FILTER的逻辑,扩展帧过滤必须在过滤规则中显式携带CAN_EFF_FLAG,否则过滤规则会匹配标准帧,导致接收异常。正确配置示例:
struct can_filter eff_filter = {
    .can_id = CAN_EFF_FLAG | 0x800, // 目标扩展帧ID,携带EFF标志
    .can_mask = CAN_EFF_FLAG | CAN_EFF_MASK // 匹配EFF标志位和全部29位ID
};
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &eff_filter, sizeof(eff_filter));
  • RecvCAN函数赋值笔误
    代码中RecvBuffer[0][0][5]=frame.data[0];属于明显笔误,应该为RecvBuffer[0][0][5]=frame.data[3];,虽然不会导致全0问题,但会导致后续数据位错位。
  • 接收后的调试逻辑错误
    你在read之后仅打印了ID,未直接打印frame的data字段,建议直接在read后增加打印逻辑,确认数据是否真的全0,排除RecvBuffer赋值导致的异常:
printf("Recv data: ");
for(int i=0;i<frame.can_dlc;i++) printf("%02X ", frame.data[i]);
printf("\n");

驱动/系统层面问题

Zynq7000的CAN控制器在Linux 3.10及以下内核版本(Ubuntu12.04默认内核版本)存在扩展帧接收的已知驱动bug,刚好表现为扩展帧ID、DLC正常,但数据字段全为0。很多Zynq用户遇到过相同问题,解决方案如下:

  1. 先使用系统自带的candump can0工具测试,确认是否能正常接收上位机发送的扩展帧:
    • 如果candump也无法正常接收数据,确定为驱动/硬件配置问题
    • 如果candump可以正常接收,就是你的应用层代码问题
  2. 驱动问题修复方案:升级内核到3.18或更高版本,或者手动回查Zynq CAN驱动的补丁,将社区后续修复的扩展帧接收补丁打到你当前的内核中。

内容的提问来源于stack exchange,提问作者Jonne gong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:30:04