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

Ubuntu16.04+Xenomai内核重启CAN电机后PCAN报I/O错误如何解决

问题根源

  1. 电机断电时CAN总线状态异常,PCAN适配器受Xenomai实时内核的IO栈调度限制,默认没有开启总线状态自动重置逻辑,内核驱动持有的硬件状态与实际硬件状态不一致,导致重新初始化进入正常工作模式时报I/O错误。
  2. 你的代码中打开端口时没有添加硬件状态重置逻辑,直接尝试进入工作模式,硬件卡在Bus Off/离线状态时就会初始化失败。
  3. 整机重启后硬件和驱动都会重新初始化,状态同步后就会恢复正常。

解决方案

1. 临时验证方案(无需修改代码)

出现错误后,直接卸载再重新加载pcan内核模块即可恢复,不需要重启整机:

sudo rmmod pcan
sudo modprobe pcan

如果执行后代码运行正常,即可确认是驱动与硬件状态不一致导致的问题。

2. 代码层面修复方案

在打开端口前添加硬件复位逻辑,同时开启驱动的Bus Off自动管理能力,修改main.cpp代码如下:

#include <sys/time.h>
#include <lcm/lcm_coretypes.h>
#include <math.h>
#include <stdio.h>  
#include <stdlib.h>
#include <sys/mman.h>
#include <inttypes.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>
#include <sys/syscall.h>
#include <pcanfd.h>
#include <libpcanfd.h>
#include <cmath>
#include <iostream>

int main(int argc, char *argv[]){
    int fd;
    // 先尝试复位设备,清除之前的异常状态
    int reset_ret = pcanfd_reset("/dev/pcan0", 0);
    if (reset_ret < 0) {
        printf("Reset device returned %d, ignore and continue open\n", reset_ret);
    }
    sleep(1); // 给硬件留足够的复位时间
    // 打开参数新增PCANFD_INIT_BUS_OFF_MANAGED,让驱动自动处理Bus Off状态
    fd = pcanfd_open("/dev/pcan0", OFD_BITRATE  | PCANFD_INIT_STD_MSG_ONLY | OFD_NONBLOCKING | PCANFD_INIT_BUS_OFF_MANAGED, 1000000);

    if (fd < 0)
    {
        printf("First open failed with err %d, retry after full reset\n", fd);
        // 首次打开失败时执行完整复位后重试一次
        reset_ret = pcanfd_reset("/dev/pcan0", 1);
        sleep(1);
        fd = pcanfd_open("/dev/pcan0", OFD_BITRATE  | PCANFD_INIT_STD_MSG_ONLY | OFD_NONBLOCKING | PCANFD_INIT_BUS_OFF_MANAGED, 1000000);
        if (fd < 0) {
            printf("Retry open still failed: %d\n", fd);
            exit(1);
        }
    }
    printf("Open succeeded with return value %d on port no. %s\n",fd, "/dev/pcan0");   
}

3. 驱动层面永久配置方案

修改pcan内核模块加载参数,开启总线异常自动复位能力,无需修改代码即可自动处理断电异常:

  1. 新建/编辑/etc/modprobe.d/pcan.conf文件,添加如下配置:
options pcan fd=1 auto_restart_ms=1000

参数说明:auto_restart_ms=1000表示总线进入Bus Off状态后1秒自动执行复位操作,可根据实际需求调整时长。
2. 执行以下命令让配置开机生效:

sudo update-initramfs -u

额外优化建议

你的项目根目录CMakeLists.txt存在冗余配置,已经直接通过add_executable(io_error_debug src/main.cpp)指定了源文件,无需再调用add_subdirectory(src),src目录下的CMakeLists.txt没有实际作用可以删除,不影响当前功能但能避免后续构建出现潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:36:04