这一节来学习一下Communication Stack中一个关键模块,那就是Com模块。
首先的了解一下AUTOSAT面向信号的通信理念,什么个意思呢?这里的信号可以理解成是应用层关心的实际值,比方说电压值,电流值,转速等,这些都是信号,应用层接收和发送信号的时候,它只需要调用相关信号的接口函数触发动作即可,至于这些信号值是通过哪种方式传送和哪种协议解析,应用层根本不关心,这就是AUTOSAR面向信号的通信理念。为了在软件中实现这个理念,Com模块在这其中起着至关重要的作用。
Com 模块位于 RTE 和 PDUR 的中间,其充当 RTE 和 PDUR 通信服务层的接口层,如下图所示:
其主要功能就是负责为上层提供各种信号的接收和传送,说得简单点一点,就是把很多信号打包成PDU(这里的PDU则是软件协议层面上的一条消息,映射到硬件上,可能是一帧或者几帧,这取决于软件协议组包的方式,比如说TCP\IP协议栈的组包),然后往各种总线上送,或者从各种总线上接收到PDU后解包成信号提供给上层。 但是众所周知,AUTOSAR就是会把简单的东西搞得及其得复杂,所以Com里面又有一大堆新玩意。
首先在介绍Com功能时,就不得不提一下DBC和LDF文件了, 在基于AUTOSAR架构进行通信协议栈的研发时,大家不可避免都会涉及到这两种文件,那么这两种文件到底有什么用呢?在这个世界还没有AUTOSAR之前,其实这两种文件就已经存在且被广泛应用,这两种文件主要定义了CAN报文(DBC文件定义)或者LIN报文(LDF文件定义)的组包方式,除此之外还有不同报文的发送和接收熟悉。
在AUTOSAR的方法论中,一切文件皆ARXML,所有输入输出文件都是ARXML文件类型,包括与DBC文件和LDF文件起到相同作用的文件,不过当时这两种文件已经特别通用,所以这两种格式的文件也无缝融入了的AUTOSAR的研发过程中,也有很多软件都能实现DBC文件和LDF文件与ARXML文件之间格式的转换。
关于DBC文件的介绍大家可以参考文章:《细说DBC(一)——初识》,关于LDF文件的介绍大家可以参考文章《LIN数据库文件LDF介绍及使用》。
Com 模块主要功能如下:
首先得强调一点就是信号和报文(PDU)的关系是一条报文会包含一个或者多个消息。 报文的发送则是由报文传输特性及信号传输特性共同决定的。首先得了解一下报文和信号各有哪些传输特性。
报文的传输特性包括:
信号的传输特性包括:
注 1:触发多次发送时,发送次数由该信号所在报文的 ComTxModeNumberOfRepetitions
属性决定。多次发送的周期,由该信号所在报文的 ComTxModeRepetitionPeriod 属性决定。
注 2:触发发送时,并非立即发送,而是需要等到下一个 Com_MainFunctionTx 的调度周期,
才开始进行发送。
所以两者结合后,导致最终一条报文最终传输特性为:
注 3:DBC和LDF对信号和报文属性的定义和AUTOSAR中定义报文属性是有点不同的,当使用AUTOSAR工具导入DBC/LDF文件时,会根据规则转换。
另外在Com模块中,还可以给每一条报文配置额外的发送模式,也就是说一条报文可以拥有两种发送规则,可改变的规则包括:1. 报文传输特性;报文重复发送周期;2. 报文重复发送次数;3. 报文发送首次偏移时间;4. 报文周期时间。
当上层程序发起信号的发送时,Com模块将信号装进PDU里并发送的过程如下图所示:
首先上层的SWC通过RTE调用对应的Signal/Signal Group接口(Com_SendSignal/Com_SendSignalGroup),请求信号发送,COM层内部置位对应信号或者信号组的Update Bits;信号的超度超过一个Byte时,需要进行字节序的转换(即:大端模式或者小端模式);随后添加信号的发送属性以及选择报文的发送模式,最后会调用PduR的接口(PduR_ComTransmit/Com_TriggerTransmit)触发报文的发送;在整个发送过程中Com会对每一条报文的发送进行定时监控;还可以为每一个PDU配置一个"I-PDU Callout",可以在PDU发送请求之前,在此Callout中实现一些特殊功能。
Com 在接收到报文后,将按照如下流程进行处理,如下图所示:
首先PduR模块通过Com_RxIndication通知Com接收到PDU后吗,首先Com模块会复位PDU对应的超时定时器Deadline Monitor Timer,如果如果配置了回调函数,则调用Com_cbkRxTout(),如有配置的I-PDU Callout,调用对应的用户接口;如果一个Signal或者Signal Group配置了Update Bits。只有Update Bits置位(=1)时,此Signal或者Signal Group才会进一步的处理,处理包括:过滤、通知、信号路由、字节序转换等。如果Signal的Update Bits未有置位,当上层再次读取该信号值时,可以使用该信号的上次历史值或者初始值;
如果用户配置了信号路由,Com 在接收到源信号后,将自动将该信号的值,写入目的发送信号,完成信号路由操作。信号路由只是对信号值的路由,不影响信号的接收和发送方式,这主要包括:
信号的路由过程如下图所示:
其实过程也很简单,收到信号后,会立马把该信号的值更新到发送PDU中去发送出去。
Com模式提供的滤波方式包括:
滤波方式 | 描述 |
---|---|
ALWAYS | 全部通过 |
NEVER | 屏蔽所有信号 |
MASKED_NEW_EQUALS_X | 满足下述条件通过,value&Mask = X |
MASKED_NEW_DIFFERS_X | 满足下述条件通过,value&Mask != X |
MASKED_NEW_DIFFERS_MASKED_OLD | 满足下述条件通过,newvalue&Mask != oldvalue&Mask |
NEW_IS_WITHIN | 通过信号值在某个范围值内的信号 |
NEW_IS_OUTSIDE | 通过信号值超出某个范围值内的信号 |
ONE_EVERY_N | 信号每 N 次滤波,通过一次 |
需要使用传输协议进行传输的报文(通常是因为报文长度较大,单帧无法进行传输),需要配置为 TP 报文。对 COM 模块而言,TP 报文与非 TP 报文的区别主要包括:
用户可以对不同的 PDU 进行分组,位于同一组内的 PDU,可以同步的进行启动或停止的操作。PDU 组的功能默认是开启的,默认的分组规则是,每个通道单独分组,每个通道分为发送和接收两个功能组。
位于功能组内的报文,在初始化后,处于关闭的状态。用户需要调用相关接口,启动该组后,组内的报文才可以正常的收发。不属于任何功能组的报文,在初始化后,处于开启的状态,可以正常进行收发。
同一报文可以属于多个功能组,称为关联组。开启一个功能组时,只开启属于本功能组的所有报文。关闭一个组时,如果该功能组有关联组,则会关闭本组及所有关联组内的所有报文。不同的功能组也可以组成一个新的功能组,这称为多级的功能组。
超时属性是属于信号属性,需要通过配置工具进行配置。但实际上,信号是不能单独进行传输的,必须以报文为单位进行传输,因此,COM 的超时监测实际是以报文为单位进行的。同一条报文中,不同信号可以配置不同超时值。报文的超时值等于信号中最小的超时值,报文中各信号的实际超时值等于报文的超时值。
发送超时是指从启动报文发送到发送确认之间的时间。如果信号的传输特性中配置了重发机制(Repetition),那么在发送超时的时间内,必须将全部重发次数发完,否则 COM 会上报发送超时(在这里简单得解释一下Repetition机制,就是有的事件型报文触发之后可以配置它在短时间内发送多次,然后这里得超时时间则指的是在超时时间内必须将多次全部发送完成)。超时后,未完成的发送将被丢弃。COM 监测到发送超时事件后,会调用 Com_CbkTxTOut 通知用户。
接收超时是指在规定时间内没有接收到报文。接收超时有两种超时:1. 首次接收超时(ComFirstTimeout),仅在下列场景使用: 初始化后;报文所在的功能组重新启动; 报文所在的功能组的接收超时重新启动。2. 正常接收超时(ComTimeout),正常情况下的超时监测。首次超时时间一般设置的比较长,因为初始化时,总线上各控制器的初始化时间可能比较长。COM 监测到接收超时事件后,会调用 Com_CbkRxTOut 通知用户,并会根据配置,执行不同的动作:1. REPLACE:使用初始值替换当前的信号值;2. NONE:无特殊动作。
为防止总线的负载率过高,用户可以为发送的 Pdu 配置最小延迟时间。配置了最小延迟时间后,在该时间内,最多只能有 1 帧报文发送到总线上。如果在该时间内有多于 1 次发送请求,则后续的请求会被退后到最小延迟时间之后发送。该时间仅对相同 PduId 的发送报文起作用,不同 PduId 的报文之间无最小延迟时间的限制。