文章目录
- PduR简介
- I-PDU缓存
- 缓存区类型
- 缓存策略
- 缓存共享
- I-PDU接收
- 接收来自通信接口的I-PDU
- 接收来自传输协议的I-PDU
- I-PDU发送
- 通信接口型发送
- 传输协议型发送
- 多播传输
- 处理未知长度I-PDU
- I-PDU网关
- 通信接口
- 网关缓存
- 立即网关
- 传输协议
- 直接网关
- On-the-fly网关
- 发送取消
- 接收取消
- 零损耗运行
- 状态管理
- 总结
在上一篇,我们介绍了CanIf模块,接下来我们介绍AUTOSAR通信结构中的核心模块——PduR(AUTOSAR PDU Router)。下图显示了 PduR在 AUTOSAR CAN通信结构中的位置。
PduR简介
PduR提供路I-PDU(Interaction Layer Protocol Data Units)的路由服务。PduR基于静态定义的I-PDU标识符来执行I-PDU的路由,在运行期间没有I-PDU被动态路由,即PduR的路由表是静态配置,配置完成后在运行时不支持更改。PduR模块主要有两部分组成:
- PduR路由路径:静态路由路径,描述的是每个被路由I-PDU的路由属性。
- PduR引擎:根据PduR路由路径执行路由功能的代码,PduR引擎要处理
- 将I-PDU从Source路由到Destination;
- 将Source的I-PDU的ID转换为Destination的I-PDU的ID(如:PduR_ComTransmit()到CanIf_Transmit(),PduR_CanIfTxConfirmation()到Com_TxConfirmation());
PduR的路由功能有三种方式:
- I-PDU转发
- 发送
- 到通信接口
- 本地模块到通信接口的I-PDU单播(1:1)。
- 本地模块到通信接口的I-PDU多播(1:n)。
- 到传输协议
- 本地到传输协议模块的I-PDU(包括单帧和多帧)单播(1:1)。
- 本地到传输协议模块的I-PDU(包括单帧和多帧)多播(1:n)。
- 到通信接口
- 接收
- 从通信接口
- 通信接口模块到本地的I-PDU单播(1:1)。
- 通信接口模块到本地的I-PDU多播(1:n)。
- 通信接口模块到本地的I-PDU的Fan-in(n:1)。
- 从传输协议
- 传输协议模块到本地I-PDU(包括单帧和多帧)单播(1:1)。
- 传输协议模块到本地I-PDU(包括单帧和多帧)多播(1:n)。
- 从通信接口
- 发送
- I-PDU网关
- 到通信接口
- I-PDU从一个通信接口模块到另一个通信接口模块以last-is-best / FIFO 缓存或无缓存的方式的1:1网关。
- I-PDU从一个通信接口模块到多个通信接口模块以last-is-best / FIFO 缓存或无缓存的方式的1:n网关。
- I-PDU从多个通信接口模块到一个通信接口模块以last-is-best / FIFO 缓存或无缓存的方式的n:1网关,此功能source端一次只能使能一个(一次只能处理一个source)。
- 到传输协议
- I-PDU从一个传输协议模块到另一个传输协议模块使用缓存的1:1网关。
- I-PDU从一个传输协议模块到多个传输协议模块使用缓存的1:n网关。
- I-PDU从多个传输协议模块到一个传输协议模块使用缓存的n:1网关,此功能source端一次只能使能一个(一次只能处理一个source)。
- 到通信接口
- 网关和转发结合
- 通信接口
- I-PDU被一个或多个上层模块接收的同时也被以last-is-best / FIFO 缓存或无缓存的方式网关到另一个或多个通信接口。
- 传输协议
- I-PDU(仅单帧)被一个多个上层模块接收的同时,也被以缓存的方式网关到一个或多个底层传输协议模块。
- 通信接口
在PduR中,牵涉到一个概念:上层和下层。其实他们分别代表着PduR路由的I-PDU的出发地和目的地。通常作为上层的是:Com 、Dcm等这种服务型模块,为I-PDU路由的目的地;作为底层的是CanIf、CanTp这种底层执行、协议模块,作为I-PDU路由的出发地。但有些模块根据使用场景不同即可做为上层(目的地)又可作为下层(出发地),比如:SecOC 、 IpduM等模块。
PDUR模块以一致的方式将I-PDU无修改地从源模块传输到目的模块。I-PDU是通过I-PDU ID或者符号名被识别。在预编译(Pre-Compile)阶段,即源码中以符号名标识每个I-PDU,但在PduR模块编译后,即程序运行中都是通过I-PDU ID标识每个I-PDU(在实际代码中,每个符号名都是宏,对应一个特定的数值)。每一个和PduR交互的模块都包含一个I-PDU ID列表,这就意味着模块者可以通过查表找到对应I-PDU。PduR通过使用源模块I-PDU ID 和 目的模块I-PDU ID区分每个路由路径。源模块的I-PDU ID 位于PduR的配置中,目的模块的I-PDU ID目的模块的配置中。PduR负责源模块I-PDU ID 转换到目的模块I-PDU ID 的转换。如:Com发送一个I-PDU到CanIf,调用Com_Transmit()启动发送。PduR将会把源I-PDU ID(由PduR配置)转换成CanIf I-PDU ID。
PduR只根据配置过程定义的路由路径进行路由,即PduR路由路径是静态配置完成的。另外,PduR不允许通过一个路由路径连接具有不同MetaDataType的IPDUs的配置。
下面,我们详细介绍下PduR的功能和属性。
I-PDU缓存
PduR可以提供I-PDU缓存的支持。I-PDU缓存目前仅可用于网关和多个通信接口到本地模块的fan-in接收。设置相关的PduRQueueDepth时,路由路径即缓存I-PDU。以下场景强制要求I-PDU缓存:
- 网关目的模块是触发传输数据提供(Trigger Transmit Data Provision)
- TP网关
缓存区类型
从路由路径分配者的视角看,缓存区有两类:全局缓存区和专用缓存区。全局缓存区指的是不被任何PduRRoutingPath引用的缓存区;专用缓存区指的是至少被一个PduRRoutingPath引用的缓存区。全局缓存区可以被任何PduRRoutingPath使用,而专用缓存区只可被引用它的PduRRoutingPath使用。
当被缓存I-PDU长度不大于专用I-PDU缓存区所配置的PduRPduMaxLength,I-PDU缓存到专用的缓存区,若被缓存I-PDU长度大于专用I-PDU缓存区所配置的PduRPduMaxLength,PduR将为该I-PDU分配一个合适的全局缓存区。
缓存策略
缓存策略是由配置参数PduRQueueDepth决定。此参数指定路由路径可以同时占用的PduRBuffers的最大数量:PduRBuffer可以来自专用缓存区也可来自全局缓存区,由于每个PduRBuffer可存放0或1个I-PDU,因此PduRQueueDepth隐式指定了路由路径可以缓冲的I-PDU的数量。如果PduRQueueDepth大于1,则缓存以FIFO的形式进行。
缓存共享
在配置上,一个PduRBuffer可以被多个PduRDestBufferRef引用,因此该PduRBuffer可以被任何一个引用PduRRoutingPath用作专用缓存区。但在任意特殊时间,只有一个PduRRoutingPath占用该PduRBuffer。
I-PDU接收
I-PDU的接收通常是以来自底层的RxIndication标志结束。由底层的RxIndication函数可以是在轮询任务种也可以是在中断服务种发起。
接收来自通信接口的I-PDU
源通信接口模块通过调用PduR_< user:Lo>RxIndication来通知PduR接收到的I-PDU,然后PduR模块调用< Up>_RxIndication通知上层目的模块,时序图如下图所示:
如果接收的I-PDU是直接转发,PduR则不对接收的I-PDU做长度校验。由于PduR不缓存该I-PDU,因此PduR不必拒绝长度大于或小于配置长度的I-PDU。如果用户不能排除并发请求n:1路由点的可能性,则需要一个FIFO来串行化并发接收请求。
接收来自传输协议的I-PDU
在接收I_PDU来自传输协议模块的时,当接收第一帧(FF)或单帧(SF)时,首先调用PduR_< User:LoTp>StartOfReception来通知PduR模块。PduR通过调用< Up>StartOfReception转发到相关的上层模块。在随后的< Up>CopyRxData调用中,每个段(N-PDU)的Payload将被复制到上层目的模块中。在接收到最后的N-PDU之后,传输协议模块将调用PduR< User:LoTp>RxIndication向PudR模块指示已经接收到完整的I-PDU,并且PduR模块将通过调< Up>TpRxIndication将该指示转发给相关的上层模块,如下时序图所示为从CanIf接收I-PDU到Dcm模块:
如果源传输协议模块使用PduR< User:LoTp>RxIndication报告错误,则PduR模块除了将RxIndication转发给上层模块之外,不应执行任何错误处理。
如果I-PDU被多个的本地上层模块接收,则向这些上层的转发以类似于直接传输协议网关的方式来处理。PduR通过PduRDestBufferRef配置的专用缓冲器(PduR buffers)缓存1:n转发的I-PDU,并在RxIndication的上下文中通知上层。
在多个上层模块接收时,PduR分别对每个上层模块接收进行错误处理,接收模块之间互不影响。当数据接收过程中出现错误时,PduR停止与相应上层接收模块的交互,不影响其他接收模块继续进行。
PduR可以使用TP API处理长度未知的I-PDU(如:流类型数据)。参数TpSduLength=0表名该I-PDU是未知长度的I-PDU。在本地接收时,当以TpSduLength=0为参数调用PduR< User:LoTp>StartOfReception时,PduR应该以参数TpSduLength=0 调用l< Up>_StartOfReception。
I-PDU发送
底层目的模块以异步方式进行发送。即当I-PDU被PduR传给底层目的模块后,发送请求就立即返回。当I-PDU发送成功或失败后,PduR被底层目的模块通过PduR_< User:Lo>TxConfirmation 或PduR_< User:LoTp>TxConfirmation通知,然后PduR通过< Up>_TxConfirmation (Communication Interface) 或< Up>_TpTxConfirmation 将此通知转发到相应上层模块。
PduR的发送操作是由上层模块PDU发送请求触发,PduR的作用是将此发送请求转发到底层的目的模块。I-PDU的发送有两种类型:通信接口发送和传输协议发送。
通信接口型发送
通过通信接口进行I-PDU发送的模式有3种:
- Direct data provision
该模式下,上层模块调用PduR_< User:Up>Transmit,PduR模块将此调用转发到
< Lo>_Transmit,并在调用中I-PDU数据由底层通信接口拷贝。 - Trigger transmit provision
该模式下,底层通信接口通过使用PduR_< User:Lo>TriggerTransmit请求传输I-PDU,PduR将此调用转发到< Up>_TriggerTransmit,并且数据由上层模块拷贝到目的地缓存区。 - 上层模块调用函数PduR_< User:Up>Transmit,PduR转发此调用到< Lo>Transmit,但此时数据不会由底层模块拷贝,而是在底层模块调用 PduR< User:Lo>TriggerTransmit时请求数据。
当通信接口调用函数PduR_< User:Lo>TxConfirmation通知PduR发送结果时,PduR需要调用函数< Up>_TxConfirmation ,将数据发送结果反馈给上层模块。以上三种模式下发送确认传输方式都是一样的。通信接口型的数据发送,PduR不做I-PDU数据长度校验。下图所示为Direct data provision模式下的一个I-PDU发送时序图。
传输协议型发送
传输协议型I-PDU发送有两种场景:单播和多播。单播传输由一个上层模块和一个底层传输协议目的地模块组成;多播传输底层传输协议目的地木块则有多个。PduR模块会检查请求的传输是一个N-PDU(单帧)或多个N-PDU(多帧,FF,CF)。上层模块通过调用函数PduR_< User:Up>Transmit发起I-PDU发送请求,PduR根据路由路径通过调用函数< Lo>_Transmit转发请求到一个或多个底层目的地传输协议模块
此时,< Lo>_Transmit可能包含数据也可能不包含数据
目的地模块通过调用函数PduR_< User:LoTp>CopyTxData请求数据,数据访问的充入性由参数RetryInfoType表征(如果传输协议支持)。最后目的地模块调用函数
PduR_< User:LoTp>TxConfirmation将数据发送结果反馈到上层。
多播传输
传输协议型I-PDU的多播传输有一些特殊的要求。由于1:n的路由是由PduR完成的,所以PduR需要多次从上层请求同一数据,每次传输的传输确认都分别处理。由于上层模块要多粗拷贝同一数据,PduR用RetryInfoPtr多次访问相同的数据,RetryInfoPtr包含了一个状态量TpDataState,目的传输协议模块不能将TpDataState设置为DATARETRY。当在传输协议型多播路由路径中,以TpDataState =DATARETRY调用 PduR_< User:LoTp>CopyTxData时,PduR返回E_NOT_OK。多播传输N-PDU的执行是锁步的方式进行,最慢的目的传输协议模块决定了传输速率。
一个新建立的传输协议多播回话,第一个目的传输协议请求的PduR_< User:LoTp>CopyTxData需要使用TpDataState参数为TP_CONFPENDING。同一个回话的后续PduR_< User:LoTp>CopyTxData 调用中,PduR重写TpDataState参数为TP_CONFPENDING,并调整 Tx TpData cnt,以从上层源缓存中与该目的地相关的前一传输点,请求用以传输的数据。
Tx TpData cnt是距离当前位置的相位
当PduR接收到最后一个来自底层处传输协议的PduR_< User:LoTp>TxConfirmation后,将会调用< Up>_TpTxConfirmation ,将传输结果返回上层。当前只要有一个底层传输模块传输返回E_OK,PduR就返回上层模块E_OK。下图所示为Dcm到CanTp的PDU传输。
处理未知长度I-PDU
PduR可以使用TP API处理长度未知的I-PDU(如:流类型数据)。参数TpSduLength=0表名该I-PDU是未知长度的I-PDU。在本地发送时,当以TpSduLength=0为参数调用PduR_< User:Up>Transmit时,I-PDU被路由到TP模块,PduR应该以参数TpSduLength=0 对所有目的传输协议模块调用< LoTp>_Transmit。
I-PDU网关
PduR支持从源总线到目的总线的I-PDU网关功能,支持1:1,1:n,n:1三种方式,但不支持n:m。此外还支持将被网关的I-PDU转发至上层模块。在网关功能中PduR充当了I-PDU的接收和发送者。网关功能设计独立于PduR,当实际PduR不要求网关功能时,可以精简PduR结构,已达到更高的效率。I-PDU的网关功能也分为针对通信接口和传输协议两种。
- 通信接口
I-PDU将被从一个或多个源通信接口网关到另一个通信接口(1:1或n:1),或者从一个源通信接口网关到多个目的通信接口(1:n)- PduR模块单独为每个目的地设置缓存类型;
- I-PDU可以在被网关到多个目的通信接口的同时被多个上层模块接收;
- 传输协议
I-PDUs从一个或多个源网关到目的传输协议模块,或者从一个源网关到多个TP模块- 单帧和多帧都可在被一个或多个本地模块(如:Dcm)接收的同时被网关到一个或多个目的TP模块;
- 多帧可以“on-the-fly”的方式网关到一个目的TP模块,这意味着不需要接收到完整的一个I-PDU即可开始往目的模块的传输;
- TP网关I-PDU必须缓存,缓存深度可配置。last-is-best型的单帧传输是不允许的。
PduR转发从一个底层模块(源网络)接收到I-PDU到另一个底层模块(目的网络),I-PDU的识别是通过I-PDU ID进行。另外,I-PDU网关只可以在同类型模块间进行,如从通信接口到通信接口或从传输协议到传输协议,不支持跨模块类型(通信接口与传输协议间)的网关功能。如果使用n:1的网关,PduR要确保在目的地保存I-PDU进来的顺序。转发+n:1的网关是不支持的,如果网关I-PDU包含Meta Data,PduR需要缓存Meta Data。
通信接口
前面介绍过,通信接口模块之间的路由有1:1 / 1:n / n:1 三种。对并行源请求,使用FIFO进行序列化:所有I-PDU应以有序的方式放入同一个公共FIFO中。对于网关,也可以为模块的每个低层通信接口目的地配置一个缓冲器(但不是本地模块)。PduR不会改变所网关数据的传输周期或频率。网关数据提供有两种方式:
- Direct data provision
目的地I-PDU的PduRDestPduDataProvision被配置为PDUR _DIRECT。当调用
< DstLo>_Transmit时,< DstLo >模块复制数据,PDU路由器不再缓存发送的I-PDU。 - Trigger transmit data provision
目的地I-PDU的PduRDestPduDataProvision被配置为PDUR _TIGGERTRANSMIT。当调用< DstLo>Transmit时,< DstLo >模块不复制数据。PDU路由器缓存发送的I-PDU,等待从< DstLo >模块调用PduR< DstLo>TriggerTransmit时复制数据。
网关缓存
由于被网关的I-PDU长度可能不同,因为PduR缓存I-PDU时以以下两种长度的最小值作为标准:
- 接收到的I-PDU长度(PduLength of received I-PDU);
- 目的I-PDU配置的长度,超出此配置长度的数据都将被丢弃;
当使用direct data provision方式的FIFO缓存方式时,当I-PDU从缓存bunffer被发送到目的模块时,PduR传递需要传输的字节数作为SduLength参数;当PduR接收到某I-PDU的PduR_< SrcLo>RxIndication而且该PDU的上次发送还没返回确认,PduR就将新到的数据队列到FIFO中;如果接收到某I-PDU的PduR_< SrcLo>RxIndication,而此时FIFO是空,且没有该I-PDU未返回的发送确认,则直接调用< DstLo>Transmit发送到来的I-PDU;当PduR< DstLo>TxConfirmation被调用,但FIFO并不为空,那么将继续调用< DstLo>Transmit发送FIFO中最老的一个数据,被发送过的数据将被从FIFO中移除。
当使用trigger transmit data provision方式的FIFO缓存方式时,当PduR< SrcLo>RxIndication被调用,且FIFO为空,接收到的I-PDU将入队到FIFO,并调用< DstLo>Transmit;当目的通信接口模块调用函数PduR< DstLo>TriggerTransmit请求I-PDU时,此时若FIFO为空,则函数返回E_NOT_OK;当FIFO不为空时,将从PduR缓存中拷贝要发送的I-PDU到目的通信模块,PduR校验底层木块提供的buffer size,如果小于将要储存的I-PDU,PduR返回E_NOT_OK 并停止后续处理(该I-PDU不会被从PduR缓存中移除);当调用PduR_< DstLo>TriggerTransmit且返回E_OK,PduR将最“旧”的数据拷贝到目的通信接口模块,并从PduR缓存中移除该I-PDU,此后若FIFO仍不为空,则继续调用< DstLo>_Transmit发送此时FIFO中剩余数据中最“旧”的I-PDU。
I-PDU网关时对PduR_< DstLo>TxConfirmation函数返回并不关心,除非是direct data provision的方式
当使用trigger transmit data provision方式的last-is-best缓存方式时(PduRQueueDepth 设置为 1),PduR只缓存最新I-PDU。
需要注意的是PDUR_DIRECT方式提供数据的网关类型不强制要求缓存;PDUR_TIRGGER_TRANSMIT方式提供数据的网管类型,PduR必须缓存,因为目的通信接口模块根据调度发送数据时,不会再调用
< DstLo>Transmit,而只调用PduR< DstLo>TriggerTransmit。此时I-PDU数据将会从PduR缓存中拷贝到目的通信接口模块用于发送。
立即网关
立即网关意味着I-PDU必须在没有PduR的任何缓冲机制的情况下被网关。这只能通过目的地direct data provision类型的通信接口网关来实现。由于被网关的I-PDU长度可能不同,因为PduR转发I-PDU时以以下两种长度的最小值作为标准:
- 接收到的I-PDU长度(PduLength of received I-PDU);
- 目的I-PDU配置的长度(超出此配置长度的数据都将被丢弃);
传输协议
可以配置一个传输协议模块接收到的I-PDU网关到n个底层传输协议模块,如1:n网关;或者n个传输协议 模块接收到的I-PDU网关到一个底层传输协议模块的fan-in(n:1)网关。并发的源请求会被使用FIFO序列化,即所有I-PDU被依次放入一个共用的FIFO中。一般来说,PduR将仅网关有效载荷,并不知道诸如SF、FF、CF、PCI等传输协议细节。但是PduR也应该支持使用全局PDU的MetaDataType进行配置带MetaData的I-PDU的网关。这种类型的I-PDU在通信接口路由或转发期间不需要特殊处理,但是对于TP路由,附加信息必须单独转发。
直接网关
直接网关的方式中,在开始传输之前要完整接收到网关的I-PDU(由多个N-PDU组成)。
若为单帧传输时,当PduR_< SrcLoTp>RxIndication返回为E_OK,则在目的传输协议模块上调用< DstLoTp>Transmit。然后使用参数TpDataState=TP_CONFPENDING或TP_DATACONF 调用PduR< DstLoTp>CopyTxData或当RetryInfoType为空,PduR将根据SduLength长度拷贝数据。如果没有足够的数据,PduR返回BUFREQ_E_BUSY,不拷贝任何数据;如果使用参数TpDataState=TP_DATARETRY(1:n网关场景)调用PduR_< DstLoTp>CopyTxData,PduR根据Tx TpData Cnt字节数,从当前位置往回设置数据拷贝起始点,然后拷贝SduLength长度的数据。若PduR无法根据请求回设位置,函数返回BUFREQ_E_NOT_OK,不改变当前读取位置点,且不拷贝任何数据。若成功回设后,可用的数据不满足拷贝要求,则也不拷贝数据,返回BUFREQ_E_BUSY。
若为多帧传输,使用参数TpDataState=TP_CONFPENDING或TP_DATACONF 调用PduR_< DstLoTp>CopyTxData或当RetryInfoType为空,PduR将根据SduLength长度拷贝数据,当最后一个目的地模的调用也完成后才增加buffer中读取点的位置;如果没有足够的数据可用,或者不是所有其他目的地传输协议模块都已经为前一帧调用了PduR_< DstLoTp>CopyTxData,则PDU路由器应返回BUFREQ_E_BUSY,而不复制任何数据;如果用以TpDataState=TP_DATARETRY调用PduR_< DstLoTp>CopyTxData,PDU路由器应返回BUFREQ_E_NOT_OK,而不复制任何数据。
On-the-fly网关
使用该方式进行网关,配置参数PduRTpThreshold,当接收到的数据大于该参数,即开始数据传输。若场景为n:1网关,即fan-in和on-the-fly同事启用,那么on-the-fly式传输仅针对第一个源,后续源数据传输以直接网关方式进行。只有目的地模块为TP模块才可以使用on-the-fly网关。
当接收数据达到PduRTpThreshold时,PduR调用< DstLoTp>Transmit发起对目的地模块的TP传输;若PduRTpThreshold=0,则调用
PduR< SrcLoTp>StartOfReception后,PduR立即调用< DstLoTp>Transmit;当PduR< SrcLoTp>StartOfReception返货E_OK式,即使没达到PduRTpThreshold,PduR也调用< DstLoTp>_Transmit开始对目的地TP模块开始传输数据。
若使用on-the-fly网关,那么PduR将不再支持已发送数据的重传;在以SduLenght=0为参数调用PduR_< SrcLo>StartOfReception函数的场景中,只支持on-the-fly网关。
发送取消
上层模块可能会取消通过通信接口模块或者通过传输协议模块传输的I-PDU,PduR会将该取消请求转发到一个或多个目的地模块。使用函数PduR_< Up>CancelTransmit 取消通信接口I-PDU发送或者取消传输协议I-PDU的转发。
发送取消功能是可选的,通过配置参数PduRCancelTransmit决定。
- 通信接口模块单个目的地传输情景下,当调用PduR_< Up>CancelTransmit后,PduR调用< Lo>_CancelTransmit取消I-PDU相应目的地模块的传输;
- 通信接口模块多个目的地传输情景下,当调用PduR_< Up>CancelTransmit后,PduR对每一个目的地模块调用< Lo>_CancelTransmit取消I-PDU的传输;
- 传输协议模块单个目的地传输情景下,当调用PduR_< Up>CancelTransmit后,PduR调用< LoTp>_CancelTransmit取消I-PDU相应目的地模块的传输;
- 传输协议模块多个目的地传输情景下,当调用PduR_< Up>CancelTransmit后,PduR对每个目的地模块调用< LoTp>_CancelTransmit取消I-PDU的传输;
对上层的返回值也因场景不同分为两类: - 单个目的地时,PduR将< Lo>_CancelTransmit或< LoTp>_CancelTransmit返回值直接返回给上层;
- 多个目的地时,所有目的地返回为E_OK时PduR才返回E_OK给上层,否则返回E_NOT_OK给上层;
接收取消
上层模块可以请求取消在传输协议模块上传输的I-PDU。PDU路由器模块将通过 PduR_< Up >取消接收。当PduR_< Up>CancelReceive被调用时,PudR模块应调用I-PDU的传输协议目的模块的
< LoTp>_CancelReceive。取消接收请求的确认是通过函数
< LoTp>CancelReceive的返回值进行的,该返回值作为
PduR< Up>CancelReceive的返回值被转发给上层模块。
零损耗运行
零损耗运行是一种优化,可以在原模块和目的地模块都是单个模块的情况下开启。例如Com模块和单个CAN总线之间,PduR_ComTransmit可直接调用CanIf_Transmit,而不经过PduR内部逻辑。这时,PduR模块变成了一个宏层
状态管理
PduR的状态机很简单,只有两个状态:PDUR_UNINIT 和 PDUR_ONLINE。状态流转如下图所示:
上电之后PduR处于PDUR_UNINIT 状态,当函数PduR_Init被调用成功完成PduR的初始化后,PduR应该处于PDUR_ONLINE状态。
在PduR处于PDUR_ONLINE状态时,PduR才可以根据路由路径进行I-PDU路由的功能
总结
PduR模块说起来就是两大功能:数据转发和网关。
- 数据转发是用于“上”和“下”层之间;
- 网关是用于相同类型模块之间,如:相同/不同 通信接口 / TP之间;
另外,在数据转发和网关时,根据需求不同又有缓存数据和不缓存数据的功能。
- 数据转发时的缓存,仅应用于trigger transmit data provision模式,因为在此模式下 < Lo>Transmit不拷贝数据,而是在目的模块请求发送数据函数PduR< User:Lo>TriggerTransmit时拷贝数据,所以PduR需要先“替”它缓存数据;
- 网关数据时,trigger transmit data provision模式必须缓存数据,direct data provision模式不强制缓存数据;