CAN、LIN报文的发送过程详解

电子说

1.3w人已加入

描述

前言

最近在研究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

LIN

正文

1.CAN报文IPDU的发送过程

1.1 COM模块发送IPDU

LIN

在COM模块中,周期报文通过Com_MainFunctionTx周期调度函数发送,事件触发型报文通过Com_TriggerIPDUSend通信服务接口发送。无论是Com_MainFunctionTx还是Com_TriggerIPDUSend最后都是调用PDUR模块的PduR_ComTransmit来发送报文,且传入到PduR模块的PduInfo->SDU数据buffer指针不为NULL。

LIN

LIN

1.2 PDUR模块发送IPDU

LIN

强调Com模块过来的Can IPDU->SDU一定不为NULL是因为它会影响报文的发送方式(1.3章节详解)。PduR模块对于Com模块的CAN IPDU直接调用CanIf_Transmit发送,CanIf收到IPDU发送请求后直接调用CanDriver的接口发送报文,Copy Data到CanController发送。

LIN

PduR模块的PduRestPdu配置容器提供了PduRDestPduDatProvision配置参数来配置每一个发送报文是直接发送还是触发式发送。

Note: 在ETAS的集成配置环境ISOLAR中这个参数无论配置成啥都不影响PduR模块的配置代码。个人认为这个PduR模块对于Can报文的发送都是直接调用CanIf_Transmit,确实不需要这个参数,所以到底是ISOLAR有问题还是确实这个参数不影响代码的生成还有待研究。

1.3 CanIf模块发送IPDU

LIN

CanIf模块提供CanIfTrggerTransmitSupport配置参数来配置CanIf模块是否支持Trigger方式发送报文。

LIN

CanIf为每一Tx IPDU提供了CanIfTxPduTriggerTransmit的配置参数。如果该报文的上层发送模块是PduR模块且配置了该参数为True,这在PduR模块就是生成PduR_CanIfTriggerTransmit的函数。

1.3.1 DIRECT发送

LIN

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发送

LIN

如果是IpduInfo->Sdu为NULL,则为TRIGGER发送方式,Can_Write --> CanIf_TriggerTransmit --> PduR_CanIfTriggerTransmit --> Com_TriggerTransmit完成IpduInfo->Sdu into Controller的数据拷贝,也就是所谓的Trigger数据发送。

1.4 Can模块发送IPDU

LIN

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报文的周期发送是通过调度表实现的,而Lin调度表存在于LinIf模块,LinIf模块在周期调用调度表的时候通过callback的方式实现IPDU的trigger transmit,也就是向上获取到sdu数据,然后调用Lin_SendFrame发送报文。调度表中的报文都是需要周期发送处理的报文,对于偶发sporadic frame的发送,COM --> PDUR -->CanIf_Transmit中设置发送flag,实现偶发帧发送。

2.2.2 Lin非偶发帧sporadic frame发送

LIN

2.3 LinIf模块发送IPDU

LIN

LinIf模块实现Lin调度表中报文的周期发送,且所有报文都是通过调用pdur模块的PduR_TriggerTransmit的callback函数完成sdu数据的获取。

LIN

LinIf模块的LinIfTxPdu配置容器中提供了LinifTxTriggerTransmitUL的配置参数,但是这个参数依赖于LinIfUserTxUL参数,如果LinIfUserTxUL配置为PDUR,则LinifTxTriggerTransmitUL参数不管有无配置,则一定为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方式发送的。

审核编辑:郭婷

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分