前言
最近在研究AUTOSAR通信协议栈的时候产生了以下几个问题:
(1)Lin数据由linif的调度表触发发送的话,com怎么控制Lin类型的PDU停止和发送了?
(2)怎么保证NM报文先发送的?
本文先梳理一遍通信协议栈的一些关键概念及重要机制,然后回答这些问题。
正文
1.Lin报文的发送机制
Lin报文的发送机制在<<Can/Lin报文的触发发送(Trigger Transmit) >>一文中已经详细讲解过,这里再简单回顾下。
Lin报文的周期发送是通过调度表实现的,而Lin调度表存在于LinIf模块,LinIf模块在周期调用调度表的时候通过callback的方式实现IPDU的trigger transmit,也就是向上获取到sdu数据,然后调用Lin_SendFrame发送报文。调度表中的报文都是需要周期发送处理的报文,对于偶发sporadic frame的发送,COM --> PDUR -->CanIf_Transmit中设置发送flag,实现偶发帧发送。我们这里主要讨论Lin周期报文的发送机制。
LinIf模块实现Lin调度表中报文的周期发送,且所有报文都是通过调用pdur模块的PduR_TriggerTransmit的callback函数完成sdu数据的获取。
LinIf模块调用PduR_LinIfTriggerTransmit函数来获取PDU数据,如果获取数据成功,则调用LinIf_SendFrame往LinDriver发送数据,如果获取数据失败则不会发送Lin报文。
那也就是说,如果找到PduR_LinIfTriggerTransmit返回失败的原因也就找到了LinIf停止发送报文的原因。
继续往下分析PduR_LinIfTriggerTransmit函数,PduR_LinIfTriggerTransmit --> Com_TriggerTransmit
分析Com_TriggerTransmit函数
Com_TriggerTransmit函数会首先会检查PDU所在的PduGroup是否Started了,如果没有Started,则Com_TriggerTransmit函数返回E_NOT_OK。、
也就是说如果PDU所在的PduGroup没有Started则Com_TriggerTransmit返回E_NOT_OK,PduR_LinIfTriggerTransmit返回失败,则LinIf_ManiFunction_<
2.NM报文和App报文的发送
如果我们使用Can网络管理的话,那么Can网络管理报文由CanNm模块控制发送,而应用报文的发送是由Com模块和ComM模块协同管理发送的,那么问题就来了:
NM报文由CanNm模块控制发送,App报文由Com/ComM模块控制发送,那么我们怎么保证每次上电/Reset后NM报文首先发送到总线上去了?
AUTOSAR标准里面没有规定NM报文和APP报文谁先发送出去的配置。但是NM模块提供了一个
Std_ReturnType Nm_GetState(
NetworkHandleType nmNetworkHandle,
Nm_StateType* nmStatePtr,
Nm_ModeType* nmModePtr
)
接口可以获取当前NM模式和状态,如果我们在请求ComM到FullCom前先确包NM模式进入到Network状态的话,那么NM报文一定会在APP报文之前发送出去。
Example:
Nm_StateType NmCurrentState; Nm_ModeType NmCurrentMode; Nm_GetState(ComMConf_ComMChannel_ComMChannel_Can_Network_0,&NmCurrentState,&NmCurrentMode); if(( NM_MODE_SYNCHRONIZE == NmCurrentMode )||( NM_MODE_NETWORK == NmCurrentMode )) { ComM_RequestComMode(ComMConf_ComMUser_ComMUser_Can_Network_0,COMM_FULL_COMMUNICATION); ComM_RequestComMode(ComMConf_ComMUser_ComMUser_Can_Network_1,COMM_FULL_COMMUNICATION); }
3.问题回答
问题1:Lin数据由Linif的调度表触发发送的话,com怎么控制所有Lin报文所在的PDU的停止和发送了?
答:LinIf通过LinIf_MainFunction --> PduR_LinIfTriggerTransmit --> Com_TriggerTransmit获取Lin报文的PDU数据,如果获取失败则不会调用LinIf_SendFrame发送报文。而Com_TriggerTransmit函数在获取PDU数据时首先会检查PDU所在的PduGroup是否Started,如果没有Started则Com_TriggerTransmit返回E_NOT_OK,最终LinIf_MainFunction停止往驱动发送报文,也就停发Lin报文。也就是说,我们通过BswM调用Com模块提供的Com_IpduGroupStart,Com_IpduGroupStop同样能控制Lin报文的停止和发送。
问题2:怎么保证NM报文先发送的?
答:需要手写代码或者通过BswM模式控制和仲裁实现。具体就是在请求APP报文所在Network进入到FullCom之前确保NM模式已经进入了NetWork状态。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !