【问题标题】:How to detect open CAN bus using CAN socket in C如何在 C 中使用 CAN 套接字检测打开的 CAN 总线
【发布时间】:2020-11-11 08:28:09
【问题描述】:

我会尽量保持简短。我有一个 C 应用程序,它使用以下方法打开可以套接字端口 ...

struct sockaddr_can lCanAddr;
struct ifreq lIfr;

if ((*aCanSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    log_error("socket not created");
    return -1;
}
strcpy(lIfr.ifr_name, CANSOCKETNAME);
ioctl(*aCanSocket, SIOCGIFINDEX, &lIfr);
lCanAddr.can_family = AF_CAN;
lCanAddr.can_ifindex = lIfr.ifr_ifindex;

....

如何检测以下情况:

  1. 当 CAN 总线损坏或没有设备连接到 CAN 端口时
  2. CAN 总线关闭错误 我尝试了一些方法,尝试定期读取或写入套接字,但这不会给我带来任何错误。谁能建议我一种检测这种情况的方法。我正在使用 C 来实现。感谢您的时间和耐心。

【问题讨论】:

  • 我添加了 Linux 作为标签,因为我认为那是您所指的套接字库。
  • 谢谢。你对这个问题有什么想法吗
  • 没用过那个库,帮不了你。
  • “库”是Linux的SocketCAN API。您可以使用socketcan 标签来询问有关它的问题。

标签: c linux sockets can-bus


【解决方案1】:

SocketCAN 使用错误帧报告 CAN 总线错误。这些是特殊的can_frames,在can_id 中设置了位0x20000000。 can_id 中的其他位和data 中的字节包含有关错误的信息。请参阅&lt;linux/can/error.h&gt; 了解更多信息。

要接收错误帧,您首先必须启用它们。 SocketCAN 支持过滤它们,但最简单的方法是全部启用它们:

can_err_mask_t optval = CAN_ERR_MASK;
setsockopt(*aCanSocket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &optval, sizeof(optval));

每次读取一个CAN帧,首先要检查它是错误帧还是正常数据帧。

通常,在您尝试发送 CAN 帧之前,您不会收到错误帧。在 CAN 总线损坏的情况下,这通常会很快导致总线关闭错误。当您收到在can_id 中设置了位 0x040 (CAN_ERR_BUSOFF) 的错误帧时,您可以检测到这一点。

如果没有设备连接到总线,我不确定您是否会收到错误帧。但是,如果驱动程序支持,可能还有另一种检查方法。如果总线上没有其他设备,则发送帧的 ACK 位不会被清除,这是 CAN 控制器可以检测到的。如果驱动程序认为未确认的帧未发送,您可以在应用程序中检测到这一点。首先,您必须设置一些选项,以便接收您发送的所有帧:

setsockopt(*aCanSocket, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &(int){ 1 }, sizeof(int));
setsockopt(*aCanSocket, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &(int){ 1 }, sizeof(int));

其次,您必须使用recvmsg() 来读取CAN 帧,以便检查msghdr 结构的msg_flags 成员。如果它包含MSG_CONFIRM 标志,则它是一个传输确认。它表明该帧已由您接收它的套接字成功发送。您可以使用它来检测 CAN 总线上是否存在其他设备。如果您发送帧并收到确认,则表明存在其他设备。如果您从未收到确认,则说明您是总线上唯一的设备(或存在其他问题)。

【讨论】:

  • 感谢您的宝贵时间和回答。我还试图捕捉错误主动和错误被动状态以及 Buss OFF。我正在检查 CAN_ERR_CRTL_RX_PASSIVE 和 CAN_ERR_CRTL_TX_PASSIVE 是否存在被动错误。 CAN_ERR_PROT_ACTIVE 用于主动错误。这是对主动和被动错误的正确检查吗?
  • 您对被动状态是正确的。对于活动状态,您需要检查CAN_ERR_CRTL_ACTIVE 位是否在data[1] 中设置。
  • 感谢您的回复。我正面临 BUS OFF 状态的问题。当总线中连接了多个设备时,我会收到 BUS OFF 状态。我正在检查 BUS OFF 状态:(lTempFrame).can_id & CAN_ERR_BUSOFF。这是错的吗?
  • 这可能意味着设备的比特率不一样。
  • 感谢您的回复。您是否知道当总线内连接多个设备时 PDO 响应丢失或远程请求响应丢失的原因是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多