我们的产品在运行于Ubuntu 14.04 LTS的基于Beaglebone Black的嵌入式系统上使用了著名的CANopen堆栈,该堆栈使用socketCAN。但是由于某些原因,即使我们使用的堆栈可以检测到CAN总线何时进入PASSIVE状态或什至BUS OFF状态,它也永远不会指示CAN总线何时从错误中恢复并退出PASSIVE或警告状态。 ,并进入非错误状态。
如果我直接(通过ioctl调用)查询socketCAN驱动程序,我是否能够检测到CAN总线何时进入和退出警告状态(小于127个错误),进入和退出警告状态。被动状态(大于127个错误)或总线关闭(大于255个错误)?
我想知道我是在浪费时间吗,还是有更好的方法来准确实时地检测CAN总线的所有状况?
答案 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
}