徽州骆驼 · 7月3日

AUTOSAR实战干货:为什么仅发出一帧CAN报文?

1. 问题背景

在软件开发初期基本上需要开发CAN驱动模块,最为常见的一类问题就是软件内部虽然在周期发送CAN帧,但是仅发出一帧?

今天小T跟大家一起来解析这个最为常见的问题原因,以英飞凌TC3XX芯片CAN驱动开发为例。

2. 过程分析

2.1 CAN发送状态分析

以TC3XX芯片为例,CAN发送一般均通过如下函数接口Can_17_McmCan_Write 对外发送CAN报文。

image.png

该函数也有相应的返回值, 相关说明如下图:

image.png

我们通过调试代码发现此时canStatus的状态为CAN_BUSY, 则表示当前CAN没有可用的Tx hardware buffer

Q1为什么没有可用的Tx hardware Buffer呢

Ans:  首先我们查看下回复CAN_BUSY的条件:

CanTxMask表示32个Tx的发送状态Bit位,其中某Bit位为1表示当前Tx Buffer处于空闲状态,为0则表示已经使用。当前可以看到是由于Line 7564行条件满足时才会进入到CAN_BUSY状态。

其中BufferIndex可理解为对应发送数据的Tx Mailobx,当前可以判断对应的Bit位为0,从而造成条件成立,导致回复CAN_BUSY。

image.png

Q2:什么情况CanTxMask中特定的Bit位为0呢?

Ans: 通过分析代码发现,CAN初始化过程会将CanTxMask全部初始化为1,如下图所示:

image.png

在调用发送函数Can_17_McmCan_Write  中,首次发送时,任意对应TxBuffer均会满足条件成立,从而能够分配得到Tx Buffer,得到Buffer之后,便会将对应Buffer的CanTxMask的Bit置位为0,进而锁住该Buffer,直到被释放之后才能够使用,如下图为锁住对应Tx Buffer代码:

image.png

Q2:什么情况下会释放这个Tx Buffer所在的Bit位呢?

Ans: 通过分析代码发现在对应的Controller发送完成中断中如下代码:

如下图为Controller0的发送完成中断代码,一级一级的追溯,最终我们可以看到中断函数中调用了函数接口Can_17_McmCan_IsrTransmitHandler

image.png

在上述函数接口中继续调用了函数接口Can_17_McmCan_lTxEventHandler

image.png

在上述TxEventHandler函数中继续调用了Can_17_McmCan_lTxEventProcessingHandler ,在该函数中我们便发现了释放Tx Buffer的地方,如下图所示:

image.png

2.2 中断分析

接下来我们看下中断是否使能了呢?很明显发现发送完成中断并没有使能,如下图所示:

image.png

Q3:如何使能CAN发送完成中断呢?

Ans: 对于英飞凌TC3XX芯片而言,总共3个Can Module, 每个Can Module有4个Can Node,所以总共有12个Can Controller。每一个CAN Controller均有如下四类中断必须进行使能:

  • CAN Rx FIFO中断:如果对应的CAN Mailbox配置为接收且Mailbox大于1,那么此时对应Mapping到这类CAN Mailbox将会触发Rx FIFO中断,而不是Rx Dedicated Buffer中断;
  • CAN Rx Dedicated Buffer 中断:如果对应的CAN Mailbox配置成接收且Mailbox等于1,那么则会触发该类中断,则不会触发Rx FIFO中断;
  • CAN Tx Finish 中断:每次CAN发送成功之后均会触发此类中断;
  • CAN Busoff中断:当发送CAN Busoff时便会触发此类中断;

这四类中断使能的前提条件有两个:

  • 配置对应CAN Controller的上述4个中断优先级且均大于0,那么上述发送完成中断则不会是灰色状态,能够加入到代码编译;
  • 将中断挂载到英飞凌中断处理模块IR上并使能中断;

上述这两个步骤统一在MCAL中IRQ模块或者OS中任意一个配置即可,无需同时配置。本文以没有OS,在MCAL中的IRQ模块中进行配置作为参考示例:

image.png

至此中断函数入口使能完毕,除此之外并没有真正意义上使能了CAN中断,此时还需要调用如下图CAN中断初始化函数挂载中断并使能中断

image.png

注意:如果仅仅调用了IrqCan_Init进行了中断初始化,只是代表挂载了中断,中断标志位能够在SRC相关寄存器置位,如果对应中断的SRE没有使能,也不会将中断传递至对应中断服务者,即CPU0,这点特别注意,许多情况下中断没有产生基本上就是这个最为简单的问题。

2.3 问题发生逻辑关系图

如下图所示为问题发生逻辑关系图:

image.png

3. 根本原因

  • 在MCAL IRQ模块中没有配置CAN相关中断以及优先级,导致中断入口没有使能;
  • 没有调用CAN中断初始化函数或者在SRC中没有使能对应的SRE位;

4. 修复措施

  • 在MCAL IRQ模块配置好CAN相关中断以及优先级,同时在调用CAN中断初始化函数并使能对应SRC的SRE中断使能位;
  • 如果存在OS则需要在OS中配置好CAT2中断并挂载中断即可;

5. 小T总结

  • 在开发任何外设驱动过程中如果需要使用中断,务必要检查中断被成功使能以及如何使能;
  • 如果出现发送不成功,首先检查CAN驱动接口的返回值是否检查,然后按图索骥便可以找到问题所在,要不怕调试,调试多了自然经验就上去了,下次就无需调试也就知道问题最有可能出在那里了。
作者:汽车小T8
来源:ADAS与ECU之吾见

推荐阅读:

更多汽车电子干货请关注汽车电子与软件专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
5681
内容数
416
汽车电子与软件行业的相关技术报道及解读。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息