概述:
本文摘录了AUTOSAR CAN通讯栈各个模块规范中关于“触发发送”的内容。文档描述了CAN驱动程序、CANIF和PDUR之间的数据传输过程,以及触发传输的使用。其中包括关于Can_Write()函数的使用和触发传输API的启用条件,包括使用触发传输接口请求发送PDU的方法。文档还提供了有关CanIf_Transmit()服务和CanIf_TriggerTransmit()服务的详细信息,以及有关CanDrv和CAN邮箱的操作方式的描述。
CAN DRIVER
[SWS_CAN_00503] ⌈ 如果触发传输API已启用此硬件对象(CanTriggerTransmitEnable = TRUE),则Can_Write()应接受SDU的空指针(Can_PduType.Can_SduPtrType = NULL)。⌋ ()
[SWS_CAN_00504] ⌈ 如果触发传输API已启用硬件对象,则Can_Write()应将SDU的空指针(Can_PduType.Can_SduPtrType = NULL)解释为使用触发传输接口的请求。如果是这样,并且硬件对象是空闲的,则Can_Write()
应调用CanIf_TriggerTransmit()
以获取PDU的数据。⌋ ()
[SWS_CAN_00505] ⌈ 如果CanDrv启用了默认错误检测:如果触发传输API已禁用此硬件对象(CanTriggerTransmitEnable = FALSE)并且PduInfo中的SDU指针是空指针,则Can_Write()应引发CAN_E_PARAM_POINTER并返回CAN_NOT_OK。⌋ ()
[SWS_CAN_00506] ⌈ 如果触发传输API(CanIf_TriggerTransmit()
)返回E_NOT_OK,则Can_Write()应返回CAN_NOT_OK。⌋(SRS_BSW_00449,SRS_BSW_00357,SRS_BSW_00369,SRS_Can_01130)
CANIF
在CanIf范围内,传输过程始于调用CanIf_Transmit()
,并在调用上层模块的回调服务<User_TxConfirmation>()时结束。在传输过程中,CanIf、CanDrv和CAN邮箱都将L-PDU仅存储一次在单个位置上。根据传输方法,这些位置是:
• CAN硬件传输对象或
• Transmit L-PDU缓冲区在CanIf内,如果启用了传输缓冲。
对于触发传输,CanIf只需存储给定L-PDU的传输请求,而不是其数据。当HTH再次空闲时,数据将通过触发传输函数及时获取。请求传输的单个Tx L-PDU永远不应存储两次。这种行为对应于CAN网络上定期通信的通常方式。
<User_TriggerTransmit> 注意:此回调服务由CanIf调用,并在相应的上层模块中实现。在CanDrv发出触发传输请求的情况下,它将被调用。
[SWS_CANIF_00888] d <User_TriggerTransmit>()的配置:提供TriggerTransmit回调服务的上层模块必须由CanIfTxPduUserTxConfirmationUL(请参见CanIfTxPduUserTxConfirmationUL)进行配置。如果未配置上层模块,则不会执行TriggerTransmit回调服务,因此不支持该PDU的触发传输功能。 c()
[SWS_CANIF_00889] d <User_TriggerTransmit>()的配置:CanIf调用的API <User_TriggerTransmit>()的名称应通过参数CanIfTxPduUserTriggerTransmitName(请参见CanIfTxPduUserTriggerTransmitName)进行配置。 c()
注意:如果未指定CanIfTxPduTriggerTransmit或为FALSE,则无需为触发传输配置上层模块。因此,将不会调用<User_TriggerTransmit>(),也不需要配置CanIfTxPduUserTxConfirmationUL和CanIfTxPduUserTriggerTransmitName。
触发发送请求顺序图
发送请求(Transmission request)
上层通过服务CanIf_Transmit()发起传输请求。参数CanTxPduId标识所请求的L-SDU。服务执行以下步骤:
• 验证输入参数
• 定义要使用的CAN控制器
第二个参数*PduInfoPtr是指向结构体的指针,该结构体包含要传输的L-SDU的大小(SduLength)。实际的SDU数据未由上层传递。因此,指针*SduDataPtr指向NULL。
开始传输(Start transmission)
CanIf_Transmit()发起传输请求,并调用CanDrv服务的Can_Write()函数进行相应的处理。处理过程中涉及HTH(Hardware Transmit Handle)的操作。
触发发送(Trigger transmission)
如果CAN硬件空闲,则Can_Write()通过其服务CanIf_TriggerTransmit()请求CanIf传输SDU数据,传递相应的L-SDU ID和指向CAN硬件缓冲区的指针。CanIf将触发传输请求转发给相应的上层(CanIfUser)。CanIf通过CanDrv接收到缓冲区指针。CanIfUser最终将SDU数据复制到CanIf提供的缓冲区(即CAN硬件缓冲区),并返回实际写入的状态和字节数。
CAN_Write()服务返回CAN_OK。
Can_Write()服务返回CAN_OK给CanIf_Transmit()。
Can_Write()服务返回CAN_BUSY。
如果CanDrv检测到没有可用的空闲硬件对象,则将CAN_BUSY返回给CanIf。
传输请求的排队(Queuing of transmission request)。
由CanDrv拒绝的L-PDU的传输请求将由CanIf排队,直到下一个传输确认。
CanIf返回E_OK。
CanIf_Transmit()向上层返回E_OK。
PDUR
数据提供。
数据提供给接口模块。数据提供有两种方式
(a) 直接数据提供:要传输的数据在传输请求时直接提供。目标通信接口可以有两种行为,一种是直接复制数据,另一种是将复制推迟到触发传输时。
(b) 触发传输数据提供:要传输的数据不是在传输请求时提供的,而是通过回调函数由接口模块检索。
PDU路由器模块是位于接口模块和传输协议模块(下层模块)之上,COM和DCM(上层模块)之下的I-PDU传输单元,参见图1。除PDU路由器模块外,还有I-PDU多路复用器(IpduM)模块[7],它提供了对多路复用I-PDU的支持。当IpduM调用PDU路由器模块以传输多路复用的IPDU或在PDU路由器模块调用它以接收或传输确认多路复用的I-PDU或通过触发传输提供数据时,它必须被视为上层模块。如果IpduM调用PDU路由器模块将传输确认或接收指示转发到上层(例如COM)或当PDU路由器模块调用它以更新属于多路复用I-PDU的I-PDU时,它必须被视为下层模块。
组播功能由于在第4.1.1节中描述的问题而被分成了自己的部分。由PDU路由器模块直接处理的其他要求包括:[SWS_PduR_00218] 如果提供的I-PDU ID表示一组PDU(多播传输请求)并且转发的传输请求中至少有一个成功返回,则函数PduR_<Up>Transmit
应返回E_OK。(SRS_PduR_06125)。请注意,返回E_OK的通信接口将直接或通过触发传输传输其数据。
I-PDU的传输确认对于直接数据提供和触发传输数据提供是相同的:[SWS_PduR_00627] 当通信接口模块调用PduR_<Lo>TxConfirmation时,PDU路由器应在上层模块中调用<Up>_TxConfirmation,并将传输结果从下层转发到上层接口。(SRS_PduR_06012)[SWS_PduR_00745] 如果I-PDU由上层模块传输,则PDU路由器模块不应检查I-PDU的长度。(SRS_PduR_06012)[SWS_PduR_00625] 当源上层模块调用PduR_<Up>Transmit时,PDU路由器应为每个目标通信接口模块调用<Lo>_Transmit。(SRS_PduR_06026)[SWS_PduR_00626] 如果是单播(1:1),则<Lo>_Transmit调用的返回值应转发到源上层模块。(SRS_PduR_06012,SRS_PduR_06104)
触发传输数据提供
必须向上层模块通知是否需要重置更新位并以适当的方式处理I-PDU计数器。[SWS_PduR_00430] PDU路由器模块应通过调用<Up>_TriggerTransmit
将通信接口模块的PduR_<Lo>TriggerTransmit
请求转发到上层模块。(SRS_PduR_06012,SRS_PduR_06032)[SWS_PduR_00661] PDU路由器模块应将<Up>_TriggerTransmit
的返回值复制到下层模块。(SRS_PduR_06104)
通信接口模块
[SWS_PDUR_00809] ⌈在最后一次最佳缓冲(请参见PduRQueueDepth)的情况下,在触发传输数据提供的情况下,PduRouter应缓冲最新的I-PDU。⌋(SRS_PduR_06032)之所以必须存储触发传输数据提供的I-PDU是因为目标通信接口可能根据时间表传输I-PDU。然后,通信接口将调用PduR_<DstLo>TriggerTransmit而不是先前的<DstLo>_Transmit调用。
[SWS_PDUR_00819] ⌈当从PduR缓冲区将I-PDU(触发传输数据提供)复制到目标模块时,PduR应检查提供的SduLength作为下层缓冲区大小。如果缓冲区对于存储的PDU数据太小,则PduR应返回E_NOT_OK并且不再进一步处理TriggerTransmit调用。()注意:如[SWS_PduR_00819]中定义的不处理TriggerTransmit调用确实意味着PDU不应从PduR缓冲区中删除。
FIFO
[SWS_PduR_00786] ⌈当调用PduR_<SrcLo/SrcLo>RxIndication并且在触发传输数据提供的情况下FIFO队列为空时,接收到的I-PDU应复制到FIFO中并调用<DstLo/DstLoTp >_Transmit。(SRS_PduR_06012,SRS_PduR_06032)
路由路径组
[SWS_PduR_00663] ⌈当与FIFO相关联的路由路径(PduRQueueDepth> 1)停止时,相应的FIFO应被清除,如果启用DET报告,则PduR应向DET报告PDUR_E_PDU_INSTANCES_LOST。(SRS_PduR_06120,SRS_PduR_06032,SRS_PduR_06124)示例:如果进行网关操作并且PDU Router模块已缓冲I-PDU并正在等待目标通信模块调用触发传输,则缓冲区将被清除,并且不可用的缓冲区将返回到目标通信接口。
Com
Com_TriggerTransmit
[SWS_Com_00475] ⌈Com_TriggerTransmit不受I-PDU最小延迟时间的干扰,不会重置最小延迟计时器,请参见ECUC_Com_00181。(SRS_Com_02045)Com_TriggerTransmit
函数的行为独立于配置的传输模式。
用例:此函数由LIN Master用于发送LIN帧。在这种情况下,触发传输可以由主时间表本身或接收到的LIN标头发起。FlexRay接口在静态部分(与FlexRay全局时间同步)请求发送PDU也使用此函数。
ComIPdu
配置项ComIPduTriggerTransmitCallout,如果为此I-PDU定义了触发传输调用,则此参数包含调用函数的名称。