打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
工程开发问题(十一):软件升级,中断标志位清除导致的连续帧刷写失败

看到标题,大家应该可以意识到:这是一个刷写问题,同时,该问题Bug还与清中断标志位相关。

1、问题描述

Boot在升级Application程序的过程中,偶发的连续帧发送失败,导致Application刷写失败。

信息补充:ECU1属于网关节点,负责将上位机(Tester)的诊断命令路由给ECU2,ECU2是待升级的节点,ECU1和ECU2之间通过CAN总线升级。

失败的工况有如下几种情况:

CASE1:

  1. ECU1发送首帧(FF)给目标节点ECU2;

  2. ECU2给出流控帧(FC)响应;

  3. ECU1收到ECU2的FC以后,根据流控信息发送连续帧(CF);

  4. ECU1在某个时刻收到一帧响应报文(eg:SF),ECU1再发送一个CF帧以后,不再给ECU2发送CF(CF还没有发送完),直到发送超时,ECU2刷写失败。

CASE2:

  1. ECU1发送首帧(FF)给目标节点ECU2;

  2. ECU2响应流控帧(FC);

  3. ECU1收到流控帧以后,

  • 连续帧在发送连续帧期间接收一帧后面不再发送连续帧(实际没有发送完),对应上图的工况(b);

  • 没有发送连续帧,导致ECU2升级失败,,对应上图的工况(c

2、原因分析

在问题工程中,首先确认CAN诊断报文的收/发,均使用中断的方式,且接收中断优先级高于发送中断优先级。对于中断的仲裁过程有疑惑的可以参考前文Aurix:中断仲裁过程

当问题出现时,发现:发送中断例程没有完全执行。为什么呢?

嵌入式开发中,程序进入中断例程以后,有一件事必不可少:清除中断标志位而本文的问题点在于中断标志位的清除动作没有设计好。为什么没有清除好呢?

首先,我们看一下,tc3xx CAN模块的中断寄存器IR(Interrupt Register),清除中断标志位的动作实质就是清除该寄存器对应的位域。怎么清除某个位域呢?手册解释:向对应的位域写“1”。eg:某个CAN报文发送完成以后,发送完成标志位TC(Transmission Completed)会自动置位( = 1),表示发送完成,之后程序跳转到发送完成中断例程,进入发送完成中断例程以后,我们会进行清除TC的操作,如果这个操作不恰当会带来Bug,本文的症结就在这。

问题工程中,清除TC标志位的代码示意如下所示:
typedef struct MCAN_IR_B_Tag{  uint32 RF0N     :1;  //Rx FIFO 0 New Message  uint32 RF0W     :1;  //Rx FIFO 0 Watermark Reached  uint32 RF0F     :1;  //Rx FIFO 0 Full  ......  uint32 TC       :1;  //Transmission Completed  .....}MCAN_IR_B_T;
typedef union MCAN_IR_Tag{ MCAN_IR_B_T B; uint32 U32;}MCAN_IR_T;/* clear TC Bit */MCAN->IR.B.TC = 1;
上述的清除TC操作(Line 17),大家觉得有问题没?看似符合C语法规则,没啥问题。但是,实际测试发现:如上的操作,会影响到其他的位域。如何影响的呢?
  • 如果向TC位域写0,TC位保持原有状态,但是其他位域全部清除( = 0);
  • 如果向TC位域写1,包括TC位域在内的所有位域清除( = 0),注意:TSW(Timestamp Wraparound)可能很快再次置位;
既然有如上的影响,和上述的Bug有何种联系呢?前述提到:CAN报文的收/发均使用中断方式,且进入中断例程之后,会清除中断标志位。如果在发送连续帧的过程中,此路CAN上又收到一帧报文,在没有进入发送完成中断例程之前,此时会优先进入接收中中断例程,在接收中断例程中,采用如上的中断标志清除动作(RF0F),就会顺带将发送完成中断标志位(TC)也给清除
CASE1 原因分析:

t0时刻,ECU2给ECU1发送报文,同时,ECU1程序请求CF帧发送;
t1时刻,ECU1的某个中断发生(other ISR),该中断的优先级高于CAN的接收和发送中断;
t2时刻,ECU1接收完ECU2发送的报文,由于ECU1的CAN接收中断优先级小于other ISR,导致接收中断挂起,同时,ECU1获得总线使用权,开始发送CF帧
t3时刻,CF发送完成,由于other ISR优先级高,无法被打断,虽然CF帧发送完成,也只能挂起发送完成中断,这样就看到了收到一帧报文还能发出一帧的工况;
t4时刻,开始执行接收完成中断例程,在清除RF0F的时候,使用上述代码,导致发送完成标志位TC被清除
t5时刻,开始执行发送完成中断例程,判断到发送完成中断标志位TC == 0,则不再处理下一帧的CF发送,直到发送超时,刷写失败。
CASE2 原因分析:

t0时刻,ECU1处于接收报文的状态,同时,ECU1也在请求发送CF帧;
t1时刻,ECU1完成接收,接收完成中断发生,程序进入接收中断例程,同时ECU1获取总线使用权,开始发送准备好的CF帧;
t2时刻,ECU1的CF帧发送完成,发送完成标志位TC置位,如果此时接收中断例程还没有完成RF0F的清除,而是在TC置位以后执行RF0F的清除动作(即:t2~t3时间),使用上述的代码进行清除操作,会将TC标志位一起清除
t3时刻,接收中断例程完成,进入发送中断例程,判断到发送完成中断标志位TC == 0,则不再处理下一帧的CF发送,直到发送超时,刷写失败。

3、解决措施

由上可以看出,问题点主要出在驱动层,即:操作IR寄存器时,清除对应位域的时候,操作不当,那应该如何操作呢?如下示意:

/* clear RF0F Bit */MCAN->IR.U32 = uint32(1 << 2);
所以,对于这种写“1”清除对应位域的寄存器,操作时,要对32 bit进行操作。Tricore中,对外设寄存器的操作,多数是32 bit指令(Instruction)。当然,该问题如果使用了厂商的MCAL,可能不会带来此问题,厂商提供的MCAL的可靠性,相比于自己开发,还是有保障的。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
基于UDS的Bootloder详解
UDS bootloader刷写报文实例解析
平台化诊断应用软件解决方案
基于CANoe的BootLoader 测试软件实现
整车刷写工具 — DPS
基于CAN的刷写流程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服