3

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

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

我想知道这样做是否会浪费我的时间,还是有更好的方法来准确、实时地检测 CAN 总线的所有状况?

4

2 回答 2

1

因此,虽然这是一个老问题,但我只是偶然发现了它(在寻找一些只是轻微相关的东西时)。

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
}
于 2020-06-17T08:59:23.890 回答
1

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

于 2019-11-18T14:13:08.593 回答