
Autosar CAN 报文发送 下期预告CAN_RX
overview
从各个BSW 模块的角度来说,can报文的走向可以用下图来表示。
但是实际上一看就会,一做就废。不过这张图还是很有参考价值的。下面我们从代码层面来解释每一步。
RTE之上的SWC
从SWC的角度想要发送一帧报文,其实也没有一帧报文的概念,应该说是把报文里面的一个signal进行赋值,发送(为了严谨下文默认报文为周期发送,不是触发模式)。那么SWC需要手动去调用一个RTE提供的write接口。这里比如信号(PDU)名字叫FACAILE, SWC叫做WO.
则: SWC 需要调用
那么这个接口是谁来实现呢。
这个接口是由 RTE 来实现。那么RTE 怎么实现呢。
RTE的实现
上面说到SWC 调用的RTE write接口,这个接口实现是RTE生成阶段自动生成,需要开发者手动配置。
这里面可以看到 RTE 实际上是接收了SWC 的数据,然后传给了 一个函数
这时候就回到了overview图里面的COM,即下图
COM 做了那些事情
首先我们先看一下被RTE调用的这个函数的形参以及返回值
这里面第一个参数指的是 signal ID. 第二个参数是SWC层给的数据地址。那么signal ID 是什么呢。
答:配置生成的,可以看配置生成的代码。可以直接去这个位置看。每一个tx 的signal 都会对应一个 编号。
好,到这里清楚了传入signal id 和 数据地址。继续往下看。
函数
在里面判断了
- 数据有效性
- com 是否init
- signal id 是否有效
判断完之后,把参数传给了内部sendsignal函数。老规矩看返回值和形参。
到这里面可以确定SWC的输入信息是有效的。下面来对这个signal进行操作。
首先要获取这个signal的配置参数。每一个signal都有自己对应的配置参数。这个配置参数在哪呢?
这里面都有什么呢?其实都是DBC 里面定义好了的内容。这里就不复制了。可以查看上面全局变量。
下面开始把signal的数据buffer copy到pdu自己的buffer里面。
然后读取一些signal的属性,进行状态赋值。比如配置的是触发模式还是周期,还是数值变化等属性进行判断,记录状态。
操作完之后进行Pdu的状态检查,这个是检查什么呢。大家都知道模式管理模块会对PDU group/ pdu 进行管理。这里检查pdu是否允许被发送。
一切就位,又记录一些状态值,后面会用上。这时候进行进一步pdu发送。当然可能到不了进一步了,因为上面的各种检查失败,可以关注一下返回值,来判断那一步错误了。
进一步发送pdu.
这一步主要是处理一下这个即将离开com的signal的pdu发送状态,以及发送模式MIXED/PERIODIC mode。这个pdu的触发标志位 会在这里面赋值。最终传给下面函数,当然如果是没有SWC一路往下走,对于周期的函数,在
也一样会被置位。这里暂不讨论。那么到了从com发送Ipdu.
这里不得不回到最开始的总览图,因为这里的名词发生了变化,从signal 变成了Ipdu.
com的ram 全局变量。关键时刻可以直接看这里。
发送的模式,和上面这么多状态位的赋值决定com的下一步骤,这里是很复杂的,可以通过下面的表来进行查询。来知道下一步是个什么情况 仅供参考。当然我们讨论的是正常能发出去的情况。
好回到主线,com开始发送ipdu了。
传入的形参是什么呢。是pdu ID 和 这个pdu的状态位。
状态位表示的是什么呢?答:可根据下面进行以一比对。
- 根据id 可以获取该pdu的ram 以及一些配置信息
可以查看配置生成的文件
- 根据上面的flag来决定是否要发送。。如果发送的话则终于发送到了PduR
PDUR 干了什么
从形参可以看出,这里包含了pdu的信息 和 pduid. 注意这里的pduid 已经不是前面的signal id. 那么则个pduid在哪里呢?
这里对buffer 以及 ID 进行了有效性判定。后面就到了PduR需要做的事情。路由!
具体路由到哪里去,就要根据pdu本身了。下面一般的会有以下几个路径。
本文讨论走到 CanIf. 如果是诊断报文需要走到TP, 如果是以太网帧需要走到socket. 如果是其他的come 也可以,需要配置cdd_com. 这里不一一说明。
下面到了CanIf层面。
CanIf做了什么
入口函数
首先读取CanIf的配置文件在静态代码里面是个全局指针,可以访问阅读。
获取到了配置参数,这边就可以对pdu本身进行一些检查,比如长度等等。
当所有信息检查完毕之后。向更底层调发送。
- CanIfTxSduId 包含pduID
- PduInfoType 包含数据
通过全局变量,配置信息来获取单个pdu信息。以及pdu的状态。
从这里面获取最终的CanId 和 使用的Controller Id 以及传输层协议CANFD 还是 CAN. 这样才可以和硬件交互。结构体
当把硬件的信息,pdu的信息,以及初始化等信息都check完毕没有问题后。开始调驱动层代码。这时候就要明确给驱动层传入了什么数据。
传入了两个
传入了这些信息,足以驱动层知道这帧报文数据哪个核,属于哪个controller,报文ID 是多少,要以CANFD 还是CAN来发送。到了mcal.
Mcal做了什么
这里面通过两个全局变量来获取CAN硬件的相关配置,和当前这帧报文的相关配置。
把这些信息都传递给了更底层的函数。
这里就牛逼喽。
- 检查是否有空闲的buffer
注意这一步得到的buffer后面需要写道寄存器里面。
把形参传入的pdu信息 复制到临时变量里面
用CAN TX 的一个寄存器结构体定义一个指针,进行赋值。
对下面
对上面寄存器赋值完成之后通过一个循环。把刚才提到的临时变量的buffer的数据,放到TxMsgBuffer
这里完结,没问题的话,数据会从CAN controller 往 收发器走了。如果一切正常的话。会有回调函数。
多谢支持下期预告CAN_RX
文章转载自公众号:汽车与基础软件
