在socketCAN linux驱动程序下检测CAN总线错误

时间:2018-10-02 17:30:22

标签: linux-device-driver can-bus socketcan

我们的产品在运行于Ubuntu 14.04 LTS的基于Beaglebone Black的嵌入式系统上使用了著名的CANopen堆栈,该堆栈使用socketCAN。但是由于某些原因,即使我们使用的堆栈可以检测到CAN总线何时进入PASSIVE状态或什至BUS OFF状态,它也永远不会指示CAN总线何时从错误中恢复并退出PASSIVE或警告状态。 ,并进入非错误状态。

如果我直接(通过ioctl调用)查询socketCAN驱动程序,我是否能够检测到CAN总线何时进入和退出警告状态(小于127个错误),进入和退出警告状态。被动状态(大于127个错误)或总线关闭(大于255个错误)?

我想知道我是在浪费时间吗,还是有更好的方法来准确实时地检测CAN总线的所有状况?

2 个答案:

答案 0 :(得分:0)

对于这个问题,我只有部分解决方案。 在使用socketCAN时,该接口被视为标准网络接口,我们可以在其上查询状态。 基于How to check Ethernet in Linux?(将“ eth0”替换为“ can0”),您可以检查链接状态。 这不是实时的,但是可以在定期线程中执行以检查总线状态。

答案 1 :(得分:0)

因此,尽管这是一个古老的问题,但我偶然发现了这个问题(在搜索只有轻微关联的事物时)。

SocketCAN提供了所有用于检测错误帧OOB的方法。 假设您的代码与此类似:

int readFromCan(int socketFd, unsigned char* data, unsigned int* rxId) {
    int32_t bytesRead = -1;
    struct can_frame canFrame = {0};

    bytesRead = (int32_t)read(socketFd, &canFrame, sizeof(can_frame));
    if (bytesRead >= 0) {
        bytesRead = canFrame.can_dlc;

        if (data) {
            memcpy(data, canFrame.data, readBytes);
        }

        if (rxId) {
             *rxId = canFrame.can_id; // This will come in handy
        }
    }

    return bytesRead;
}

void doStuffWithMessage() {
    int32_t mySocketFd = fooGetSocketFd();
    int32_t receiveId = 0;
    unsigned char myData[8] = {0};
    int32_t dataLength = 0;

    if ((dataLength = readFromCan(mySocketFd, myData, &receiveId) == -1) {
        // Handle error
        return;
    }

    if (receiveId & CAN_ERR_MASK != 0) {
        // Handle error frame
        return;
    }

    // Do stuff with your data
}