ARM Linux CAN 异常排查步骤

ARM Linux CAN 异常排查方法

1. 背景

项目上经常有反馈,说我们的CAN总线相关设备不受控,或者控制板重启也没用。登陆系统后查看,会发现经常出现CAN通信异常或超时的情况,由于我们的控制程序在CAN总线上连续6秒接收不到信息就会异常退出。所以表象上,经常只能看到CAN总线超时退出的程序打印日志。

这样显然是不利于问题偏差的,如何更容易定位问题,弄清哪里坏了,是现在需要解决的问题。本文最后会提供一个基于ARM Linux CAN的问题排查方法。

2. 进一步探索

后续发现我们使用的libsocketcan这个开源库中,有一个接口叫can_get_state,这个接口里可以读到当前CAN芯片的状态值。

这个接口里开源库的描述是这样的:

/**
 * @ingroup extern
 * can_get_state - get the current state of the device
 *
 * @param name name of the can device. This is the netdev name, as ifconfig -a shows
 * in your system. usually it contains prefix "can" and the numer of the can
 * line. e.g. "can0"
 * @param state pointer to store the state
 *
 * This one stores the current state of the can interface into the given
 * pointer. Valid states are:
 * - CAN_STATE_ERROR_ACTIVE
 * - CAN_STATE_ERROR_WARNING
 * - CAN_STATE_ERROR_PASSIVE
 * - CAN_STATE_BUS_OFF
 * - CAN_STATE_STOPPED
 * - CAN_STATE_SLEEPING
 *
 * The first four states is determined by the value of RX/TX error counter.
 * Please see relevant can specification for more information about this. A
 * device in STATE_STOPPED is an inactive device. STATE_SLEEPING is not
 * implemented on all devices.
 *
 * @return 0 if success
 * @return -1 if failed
 */

int can_get_state(const char *name, int *state)

这里解开了CAN机制的一角,CAN总线的错误机制比较复杂,需要了解的较多。这里有篇写的不错的博客可以分享:

  1. CAN总线学习笔记(3)- CAN协议错误帧
  2. CAN总线学习笔记(1)- CAN基础知识

这里只说简单的便于理解的结论:

3. 需要了解的CAN机制相关背景结论:

  1. CAN是差分电路,有两根线。其中显性电平为逻辑0,隐性电平为逻辑1。显性电平、隐性电平同时往总线上丢,会呈现显性电平

  2. 当总线上的上出现连续的11位隐性电平,那么总线就处于空闲状态。

  3. 可以存在多个发送者,但是同一时刻只能有一个发。

  4. 逐位仲裁:当多个节点同时向总线发送消息时,对各个消息的标识符(即ID号)进行逐位仲裁,如果某个节点发送的消息仲裁获胜,那么这个节点将获取总线的发送权,仲裁失败的节点则立即停止发送并转变为监听(接收)状态

  5. 所有的节点都可以检测出错误(错误检测功能);
    检测出错误的节点会立即通知总线上其它所有的节点(错误通知功能);
    正在发送消息的节点,如果检测到错误,会立即停止当前的发送,并在同时不断地重复发送此消息,直到该消息发送成功为止(错误恢复功能)

  6. CAN协议中规定,所有数据,当相同极性的电平持续五位时,则添加一个极性相反的位

  7. 错误帧

    主动错误标志:6个连续的显性位;
    被动错误标志:6个连续的隐性位;
    错误界定符:8个连续的隐性位。

错误标志本身就是一种错误。

这里扩展一点,主动错误模式实际上错误标志位会覆盖总线上其他数据。但是被动错误由于是14个或者更多的隐性位,所以不影响其他节点的收发。

  1. CAN总线每个节点有两个错误计数器,接收错误计数器和发送错误计数器,一般大体上来说,错误计数器会在节点出于对应状态的时候,探测到错误的时候+8,正常的时候-1。累积到128和255的时候,会发生节点状态转换。具体加减规则请查阅此文章:CAN总线学习笔记(3)- CAN协议错误帧

  2. 错误主动,错误被动两个状态都能正常通信。 这里有些博客会有误导说错误被动只能收不能发,实际是不正确的。出于BUS OFF状态的,无法和总线通信。只能等128个连续11隐性位。

4. 系统正常情况下,各个节点的状态值,以及有问题之后的演变:

  1. 一般情况,正常的时候,每个节点大多数时间出于CAN_STATE_ERROR_ACTIVE这个状态,也就是错误主动状态。别看这个状态名字叫错误,但是实际上就是对应的普通状态。标示这个节点检测到错误,会发出主动错误标示。

  2. 随着问题的增多,节点逐渐会升级到CAN_STATE_ERROR_WARNING状态。但是这个状态并没有固定的硬件标示,实际上是一个软件层面的预警。也就是说,对于CAN_STATE_ERROR_ACTIVECAN_STATE_ERROR_WARNING而言,这个节点的任何逻辑行为(包括软硬件)都不会有什么区别。

  3. 随着问题的继续增多,节点会升级到CAN_STATE_ERROR_PASSIVE状态。在这个状态下,节点的硬件行为会改变,收到错误的时候,发送的是被动错误标示。

  4. 如果此时问题还会继续,则节点会进入CAN_STATE_BUS_OFF状态。这个时候只有检测到128个连续的11个隐性位才能回到CAN_STATE_ERROR_ACTIVE

5. 系统状态变换分析

  • 最初情况下,有少量错误的时候,某个节点错了一次,总线上大家都会接收到主动错误标示,计数器会+8,但由于错误较少,后续如果一直正常,那么大家都是和平的。基本还是都会在0。

  • 当某个节点本身出现了问题,总在错的时候,刚开始大家检测到错误都会报告错误,然后由于节点在发送状态的时候检测到错误是+8,节点处与接收状态检测到错误+1。所以,那个错误的节点会迅速进入错误被动状态,他发现错误也只能报告错误被动标示,错误被动标示实际上是不影响总线数据的。

  • 当这个节点一直出问题,那么后续会继续跌到CAN_STATE_BUS_OFF状态。此时这个节点理论上要听到128次总线空闲才能重新回来。(这里也修正一种说法,出于BUS OFF状态的节点就一辈子回不来了,这也是错误的

6. 了解到这些知识后,ARM LINUX层可以看那些地方加速排查问题呢?

6.1 cat /proc/net/can/stats

这个文件记录了can节点的收发情况,还有帧正确率,一个异常的现场看到如下的信息:

    69227 transmitted frames (TXF)
 14288017 received frames (RXF)
        0 matched frames (RXMF)

        0 % total match ratio (RXMR)
        7 frames/s total tx rate (TXR)
     1562 frames/s total rx rate (RXR)

        0 % current match ratio (CRXMR)
        8 frames/s current tx rate (CTXR)
      917 frames/s current rx rate (CRXR)

        0 % max match ratio (MRXMR)
       10 frames/s max tx rate (MTXR)
     4894 frames/s max rx rate (MRXR)

        1 current receive list entries (CRCV)
        1 maximum receive list entries (MRCV)

        1 statistic resets (STR)

正常业务上,这个节点的发送应该是每秒8帧,接收应该是每秒40帧。而实际上这个记录上看来接收的帧数明显超大,峰值甚至到了4.8K,而且匹配率是0%,明显应该是由于有一个节点在疯狂输出导致的。

6.2 ifconfig can0

在CAN0的ifconfig中,有droperroroverruncollisions等信息,一样可以辅助判断问题。

can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:1251704 errors:0 dropped:0 overruns:0 frame:0
          TX packets:312926 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:10013632 (9.5 MiB)  TX bytes:2503408 (2.3 MiB)
          Interrupt:25

7. 排查方法

  1. 查看can_get_state中,对应的当前芯片的错误状态。

  2. 查看cat /proc/net/can/stats中的匹配率和每秒收发频率。

  3. 查看ifconfig can0droperroroverruncollisions

  4. 结合can错误状态,收发频率,其他数值,结合上文can机制进行分析。

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
回答: 在Ubuntu上安装arm-linux-gcc的详细步骤如下: 1. 首先,需要配置系统环境变量。可以在“~/.bashrc”文件中添加一行“export PATH=&PATH:/usr/local/arm/arm-2009q3/bin”,这个路径是arm-linux-gcc命令的位置。\[1\] 2. 接下来,需要解压压缩包到根目录。使用tar命令进行解压,根据压缩包的后缀信息可以看出使用了bzip2压缩,然后使用tar命令进行分包。命令如下:sudo tar -xjvf arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2 -C /。\[2\] 3. 在安装过程中可能会遇到问题,比如提示“Package ia32-libs is not available”。这可能意味着该软件包缺失、已被废弃,或者只能从其他源获取。然而,可以使用以下软件包替代它:lib32ncurses5和lib32z1。\[3\] 以上就是在Ubuntu上安装arm-linux-gcc的详细步骤。 #### 引用[.reference_title] - *1* [ubuntu下安装arm-linux-gcc](https://blog.csdn.net/Ultraman_hs/article/details/52745372)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Ubuntu安装arm-linux-gcc 详细步骤](https://blog.csdn.net/qq_43743762/article/details/105014477)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Ubuntu16.04 安装 arm-linux-gcc方法步骤](https://blog.csdn.net/qq_37172182/article/details/83145731)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值