编辑推荐: |
本文主要介绍了Can/Lin报文的触发发送(Trigger
Transmit)相关内容。 希望对您的学习有所帮助。
本文来自于微信公众号汽车电子嵌入式,由火龙果软件Linda编辑、推荐。 |
|
前言
最近在研究AUTOSAR通信协议栈的时候发现对IPDU的Trigger Transmit很是疑惑,产生了以下几个问题:
(1)Com模块的IPDU的trigger发送和CanIf或者Can模块的Trigger发送一样吗?
(2)怎么通过CanIf模块发送trigger IPDU?
(3)哪个模块完成Can trigger IPDU的判断?
(4)请说明Can IPDR的Trigger Transmit的整个过程?
(5)Lin IPUD和Can IPDU的trigger transmit有何异同?
本文先梳理一遍CAN、LIN报文的发送过程,然后回答这些问题。
AUTOSAR 通信服务-Com模块概念详解
AUTOSAR 通信服务-PDU Router
AUTOSAR CAN通信协议栈分析(3)-CanIf
Can通信协议栈分析(1)-Can Driver
1.CAN报文IPDU的发送过程
1.1 COM模块发送IPDU
在COM模块中,周期报文通过Com_MainFunctionTx周期调度函数发送,事件触发型报文通过Com_TriggerIPDUSend通信服务接口发送。无论是Com_MainFunctionTx还是Com_TriggerIPDUSend最后都是调用PDUR模块的PduR_ComTransmit来发送报文,且传入到PduR模块的PduInfo->SDU数据buffer指针不为NULL。
1.2 PDUR模块发送IPDU
强调Com模块过来的Can IPDU->SDU一定不为NULL是因为它会影响报文的发送方式(1.3章节详解)。PduR模块对于Com模块的CAN
IPDU直接调用CanIf_Transmit发送,CanIf收到IPDU发送请求后直接调用CanDriver的接口发送报文,Copy
Data到CanController发送。
PduR模块的PduRestPdu配置容器提供了PduRDestPduDatProvision配置参数来配置每一个发送报文是直接发送还是触发式发送。
Note: 在ETAS的集成配置环境ISOLAR中这个参数无论配置成啥都不影响PduR模块的配置代码。个人认为这个PduR模块对于Can报文的发送都是直接调用CanIf_Transmit,确实不需要这个参数,所以到底是ISOLAR有问题还是确实这个参数不影响代码的生成还有待研究。
1.3 CanIf模块发送IPDU
CanIf模块提供CanIfTrggerTransmitSupport配置参数来配置CanIf模块是否支持Trigger方式发送报文。
CanIf为每一Tx IPDU提供了CanIfTxPduTriggerTransmit的配置参数。如果该报文的上层发送模块是PduR模块且配置了该参数为True,这在PduR模块就是生成PduR_CanIfTriggerTransmit的函数。
1.3.1 DIRECT发送
CanIf模块的CanIf_Transmit接口函数本身并不会判断传入的IPDU是否是需要Trigger发送(仅仅会做一些Det的检测),而是直接调用Can_Write来发送IPDU,由Can模块通过传入的IpduInfo->Sdu是否为NULL来确定是DIRECT发送还是TRIGGER发送IPDU。
如果是IpduInfo->Sdu不为NULL,则为DIRECT发送方式,Can_Write直接完成Copy
Data into controller完成报文的发送。
1.3.2 Trigger发送
如果是IpduInfo->Sdu为NULL,则为TRIGGER发送方式,Can_Write -->
CanIf_TriggerTransmit --> PduR_CanIfTriggerTransmit
--> Com_TriggerTransmit完成IpduInfo->Sdu into
Controller的数据拷贝,也就是所谓的Trigger数据发送。
1.4 Can模块发送IPDU
Can模块提供CanTriggerTransmitEnable配置参数来配置是否使用Trigger
Transmit功能。Can模块完成IPDUD最终的Trigger发送。
2.LIN报文IPUD的发送过程
2.1 COM模块发送IPDU
COM模块统一了所有IPUD的处理方式,和1.1节完全一样。
2.2 PDUR模块发送IPDU
2.2.1 Lin偶发帧sporadic frame发送
Lin报文的周期发送是通过调度表实现的,而Lin调度表存在于LinIf模块,LinIf模块在周期调用调度表的时候通过callback的方式实现IPDU的trigger
transmit,也就是向上获取到sdu数据,然后调用Lin_SendFrame发送报文。调度表中的报文都是需要周期发送处理的报文,对于偶发sporadic
frame的发送,COM --> PDUR -->CanIf_Transmit中设置发送flag,实现偶发帧发送。
2.2.2 Lin非偶发帧sporadic frame发送
2.3 LinIf模块发送IPDU
LinIf模块实现Lin调度表中报文的周期发送,且所有报文都是通过调用pdur模块的PduR_TriggerTransmit的callback函数完成sdu数据的获取。
LinIf模块的LinIfTxPdu配置容器中提供了LinifTxTriggerTransmitUL的配置参数,但是这个参数依赖于LinIfUserTxUL参数,如果LinIfUserTxUL配置为PDUR,则LinifTxTriggerTransmitUL参数不管有无配置,则<User_TriggerTransmit>一定为PduR_TriggerTransmit,也就是PduR模块一定会生成一个PduR_TriggerTransmit配置callback函数。
2.4 Lin模块发送IPDU
Lin模块没有trigger transmit的判断,提供Lin_SendFrame的接口即可。
3.问题回答
问题1:Com模块的IPDU的trigger发送和CanIf或者Can模块的Trigger发送一样吗?
答:Com模块的IPDU的trigger发送和CanIf或者Can模块的Trigger发送不一样。
Com模块的trigger transmit是某个事件触发是调用Com_TriggerIPDUSend发送IPDU,但是无论是Com的周期发送Com_MainFunctionTx还是Com_TriggerIPDUSend发送IPDU,都是调用PduR_ComTransmit,而PDUR->CanIf->Can对于Com来的IPDU都是统一以DIRECT的方式直接Copy
Data到Can Controller。
CanIf模块本身不做IPDU是否需要trigger transmit的判断,而是直接将IpudInfoPtr传递给Can模块,Can模块中通过IpduInfoPtr->Sdu是否为NULL来绝对是使用DIRECT的方式还是trigger
transmit/也就是向上调用callback后set buffer来发送报文。
问题2:怎么通过CanIf模块发送trigger IPDU?
答:CanIfUser(可以自定义一个模块,或者是其他模块)在调用CanIf_Transmti发送报文的时候传入的IpduInfoPtr->Sdu
== NULL同时CAN模块需要enable trigger transmit就可以实现CAN IPDU使用CanIf模块trigger
transmit。
问题3:哪个模块完成Can trigger IPDU的判断?
答:CanDriver模块。
问题4:请说明Can IPDR的Trigger Transmit的整个过程?
答:CanDriver模块通过判断CanIf模块传入的IpduInfoPtr-Sdu为NULL且Can模块enbale了trigger
transmit后调用CanIf_TriggerTransmt -> PduR_TriggerTransmt
-> Com_TriggerTransmt完成Copy Data into Controller的数据拷贝操作,之后通过Can发送报文。
问题5:Lin IPDU和Can IPDU的trigger transmit有何异同?
答:
相同点:IPDU的trigger transmit都是最后调用Com_TriggerTransmit函数实现的。
不同点:Lin IPDU如果是非偶发帧(sporadic frame)在通过调度表发送时都是使用trigger
transmit分方式发送的且COM -> PDUR对LIN IPDU的发送无影响;而Can
IPDU的周期发送主要是通过COM -> PDUR向下传递IpduInfoPtr通过DIRECT方式发送的。 |