我们先简单总结一下CAN的错误处理与故障界定:

1.CAN控制器记录发生在发送/接收过程中,总线数据出现错误的总数(位错误,CRC错误等)。

2.CAN控制器根据总线出错数量由低到高,依次处于主动错误状态,被动错误状态,以及总线关闭状态。

3.位于主动错误的节点,在检测到错误时,可以发送主动错误标志(6位显性位),告知总线上所有节点发生了总线的错误,之后进行正常的收发操作。保证如果总线CAN_H与CAN_L出现短路等会影响整个总线通讯的问题时,各个控制器会迅速反应。

当随着发送/接收错误总数的增加,节点将位于被动错误状态,当检测到总线发生错误的时候,将等待总线出现被动错误帧(连续6位隐性位),之后才可正常进行收发操作。保证如果总线因为线长或者节点数增大,远处的节点干扰严重,则干扰严重的节点将不会影响其余节点的正常通信。

如果发送错误总数达到了255,则进入bus-off状态,处于这种状态的节点将会与总线隔离,直到检测到128 次出现11 个连续“隐性”位后,才可以恢复错误主动状态,错误计数器 也清零。

1.Linux SocketCAN

Linux 4.17.0-RC6 内核网络部分增加了SocketCAN,用于Linux的CAN协议的一种实现。以前的嵌入式开发板的CAN驱动是以基于字符串设备的驱动注册到内核中,新的内核使用Berkeley套接字API,Linux网络堆栈并将CAN设备驱动程序作为网络接口来实现。CAN套接字API的设计与TCP / IP协议尽可能相似,以便熟悉网络编程的程序员轻松使用CAN套接字进行CAN通信。具体详细的特性介绍详见https://www.kernel.org/doc/html/latest/networking/can.html。其中章节“Network Problem Notifications中介绍了一种CAN总线错误的记录机制,SocketCAN将所有总线上的错误包装成一个“错误帧”,注意这块的“错误帧”不是CAN总线上实际跑的错误帧,而是驱动部分将控制器或者总线上的检测的错误,包装成一个CAN帧,上报给基于网络层之上的用户程序。

我们在linux4.9内核E:\linux-4.9\linux-4.9\drivers\net\can目录下的Makefile中看到内核支持了包括SJA1000,以及赛灵思的开发板的CAN驱动支持,我们比较关心的CAN错误的定义呢,在E:\linux-4.9\linux-4.9\include\uapi\linux\can中定义了所有CAN总线可能上报给用户层的错误信息具体的关系图如下:

三个能展开的三级目录分别如下:

这其中我们举个例子来说明这个伪造的错误帧是如何产生的,以AT91的驱动为例,下面的描述均来自内核源码。首先在设备的Open函数处注册了中断处理函数at91_irq,函数在发生终端时候,判断中断类型为错误中断,调用at91_irq_err处理设备错误信息,细分中断源来定义当前新状态为bus-off、报警、主动错误状态还是被动错误状态,如果状态发生了变化,则调用at91_irq_err_state形成错误帧进行上报。假如这个时候如果原状态为主动错误,而新的状态为RX/TX错误计数达到报警状态,则会更新设备当前状态,并向上层监听端口的用户程序发送一个表示控制器错误-->RX/TX错误计数达到报警状态的错误帧。用户程序就可以知道CAN总线发生了这样的错误,并检查干扰源。

2.STM32F10x bxCAN

工业现场的总线上一般有两种设备,一种为普通的can节点设备,他们在整条总线上按需分布,反馈一些即时的信息(传感器信息或者摁键等),另一种设备一般一根CAN总线上就一台这样的设备,它负责将CAN总线上的数据转发到以太网接口,WIFI,或者zigbee等通信接口,或者它本身带有屏幕,显示各个节点上报的信息并进行统一的控制。这种类似‘网关’的设备一般会上嵌入式实时操作系统,或者linux内核裁剪一下拿QT做做界面,或者直接就安卓了。

反观线上多数的设备,一般为了压低成本等原因,会采用STM32来进行开发,而总线上的状态,往往是这些处于总线远端的设备能更好的体现,并且出问题的设备也大概率会是这些设备,但是这些设备往往没有实时操作系统,业务开发起来比较缓慢且不易多人维护,导致往往对于异常的处理不足,关注实现往往大于功能实现的效率以及质量。而其更没有Linux比较完善的官方驱动支持,如上文一样可以给用户程序主动报一些总线上的错误。所以,基于STM32开发CAN的时候,更应该借鉴Linux的驱动实现方式,对总线上的错误进行记录,方便查询。

我们首先来分析一下STM32 bxCAN的错误中断源:

由上图可知,ERRIE为错误中断的总使能位,EWGIE为错误警告中断使能,当接收/发送的错误数到达报警标准之后触发此中断,EPVIE为错误被动中断使能,当接收/发送的错误数到达被动错误标准时触发此中断,BOFIE为离线中断使能,当接收/发送的错误数到达离线标准时触发此错误,LECIE为上次错误号中断使能,当接收/发送出现错误的时候,且与上次错误不同,触发此中断,错误号根据手册能表示一下错误:000: No Error,001: Stuff Error,010: Form Error,011: Acknowledgment Error,100: Bit recessive Error,101: Bit dominant Error,110: CRC Error,111: Set by software。

在发送过程,bxCan有三个发送mailbox,STM32的库函数CAN_Transmit负责将数据放到mailbox中并触发发送(若没有空闲的mailbox则返回错误),由手册可知,可根据TME来判断mailbox是否可能,库函数CAN_TransmitStatus封装好能够直接获得当前mailbox的状态,这里建议对CAN控制器的CAN_NART配置为DISABLE,使能报文重传功能,这样报文如果发送失败,将在SCHEDULED和TRANSMIT两个状态切换,直到发送完毕,才会释放邮箱。除非你的应用需要报文发送的准确时间点进行记录,并且你的应用实时性要求也不高,能够腾出时间去处理报文重传(如果你把CAN控制器的报文重传功能去掉了,那你必然要自己实现)。从这个流程中可以看出,我们可以将发送溢出(邮箱占满),以及发送仲裁丢失作为控制器的错误记录下来。

在接收过程中,就有接收溢出的中断可供记录接收溢出错误。

综上所述,STM32F10x bxCAN提供的寄存器能够满足类似Linux的除了收发器其余的所有错误记录,通过库函数能够很方便的将CAN控制器的状态变化以及总线上的错误记录下来,从而可以分析现场CAN总线的状态。

CAN总线错误分析方法相关推荐

  1. uvm 形式验证_一种基于UVM的总线验证方法与流程

    本发明涉及芯片设计的功能验证领域,尤其是一种基于UVM的总线验证方法. 背景技术: 随着集成电路工艺的不断进步,集成电路的规模和复杂度也在不断地提高,验证的难度也越来越大.在集成电路设计中,验证工作已 ...

  2. 嵌入式DSP上实现FlexRay总线的方法

    摘要 研究基于MFR4200的FkxRay总线在嵌入式数字信号处理器OMAP5912上的实现.整个系统以DSP为核心,采用Freescale公司的MFR4200总线控制器实现FlexRay通信协议,进 ...

  3. can总线rollingcounter_CAN总线错误分析与解决

    CAN总线错误分析与解决 背景 写这篇文章是因为我看到网上介绍CAN总线错误处理的文章,清一色的都是生搬照抄教科书或是数据文档的内容,特别是国内很难找到一些有价值的内容,这让一些真正有需要的人很苦恼, ...

  4. VUE3前端笔记 Mitt事务总线使用方法

    VUE3前端笔记 mitt事务总线使用方法 1. 第三方总线插件mitt (1)Vue CLI图形界面安装 (2)npm命令方式安装 2. 全局总线 ①vue入口文件main.js中挂载全局属性 ②组 ...

  5. Altium Designer 09 (Protel)总线使用方法(解决导入PCB无网络标号问题)

    转载于:http://blog.sina.com.cn/s/blog_6f444b450101pdja.html 弄了两天的Protel总线问题终于解决了,一开始顶层总线连接好后,导入PCB没有网络标 ...

  6. simulink bus总线创建方法

    在simulink中创建bus总线,主要包含2种方法: 基于模块创建总线对象 使用模块,根据输入信号创建总线 基于 MATLAB 数据创建总线对象 可以使用 Simulink.Bus.cellToOb ...

  7. adum1201参考电路_采用ADuM1201的CAN总线隔离方法

    引言 (中国矿业大学 李英 徐钊 ) CAN(Controller Area Network)[3]总线又称控制局域网络,最早由德国BOSCH公司推出,用于汽车内部测量与执行部件之间的数据通信,CAN ...

  8. 汽车用SENT总线解码方法-Pico示波器解码

    SENT 全称:Single Edge Nibble Transmission,是美国机动车工程师学会SAE推出的一种点对点的.单向传输的方案,被用来在汽车中的传感器和电子控制单元(ECU)之间传输高 ...

  9. 王牌电视显示墙服务器,TCL王牌电视机总线进入方法大全

    编号: 255 品牌: TCL 型号: dlp61v6p CPU型号: oem 参数: 待机状态下,同时按住"音量减"和"节目减"键8秒. 备注: 号: 157 ...

最新文章

  1. Python访问街区所有节点最短路径问题,并结合matplotlib可视化
  2. html新增了哪些功能,HTML5相比HTML新增了哪些功能?
  3. python保留关键字列表
  4. 客户要求ASP.NET Core API返回特定格式,怎么办?(续)
  5. Python 字符串查找子串的方法之 index() 和 find()
  6. 如何优雅地添加MGR节点?
  7. 反射 数据类型_Java基础:反射机制详解
  8. 阿里云国际版云服务器Linux和Windows操作系统的链路测试工具-Unirech
  9. c++ set用法详解
  10. 量子力学 or 线性代数(六——动量、能量)
  11. 【笔记】HEFT——面向异构计算的高性能、低复杂度任务调度
  12. 使用OTP动态口令(每30s变一次)进行登录认证
  13. Excel如何批量选中多张图片?
  14. 小程序实现canvas添加图文
  15. pdf实现页眉或者页脚代码
  16. 【技术网站分享】全面整理了一波技术网站,分享给大家!
  17. 用dom4j实现对象和xml文件的互相转换
  18. Centos7学习——echo命令
  19. abaqus 复合材料edit composite layup中报错:没有指定坐标系
  20. 【51单片机】连接蓝牙模块(AT模式、解决返回乱码)

热门文章

  1. python 程序员专属情话_拿来就能用!Python 每天定时发送一句情话 | 原力计划
  2. Beautifully crafted open source icons
  3. java电商网站建设教程_java开发电商系统实战开发视频教程
  4. php关注账号,一键关注微信公众平台账号
  5. 《OKR工作法》学习总结
  6. 07_音频录制01_命令行
  7. 用python计算邮费考虑是否加急,用python计算residuals
  8. 基础数据类型补充 set集合 深浅拷贝
  9. java rds 数据库_JDBC(java数据库连接)和阿里云RDS数据库
  10. AD软件自动添加原理图标注