目录
[3.1I-PDU handling](#3.1I-PDU handling)
[3.1.1 I-PDU Reception to upper module(s)](#3.1.1 I-PDU Reception to upper module(s))
[3.1.1.1 Communication Interface](#3.1.1.1 Communication Interface)
[3.1.1.2 Transport Protocol](#3.1.1.2 Transport Protocol)
[3.1.2 I-PDU Transmission from upper module(s)](#3.1.2 I-PDU Transmission from upper module(s))
[3.1.2.1 Multicast](#3.1.2.1 Multicast)
[3.1.2.2 Communication Interface](#3.1.2.2 Communication Interface)
[3.1.2.2.1 Trigger transmit data provision](#3.1.2.2.1 Trigger transmit data provision)
[3.1.2.3 Transport Protocol](#3.1.2.3 Transport Protocol)
[3.1.2.3.1Multicast transmission](#3.1.2.3.1Multicast transmission)
[3.1.3 I-PDU Gateway](#3.1.3 I-PDU Gateway)
[3.1.3.1 Communication interface modules](#3.1.3.1 Communication interface modules)
[3.1.3.2 Transport Protocol](#3.1.3.2 Transport Protocol)
[3.1.3.2.1 Buffer allocation](#3.1.3.2.1 Buffer allocation)
[3.1.3.2.2 Direct gatewaying](#3.1.3.2.2 Direct gatewaying)
[3.1.3.2.3 Forwarding to upper layers](#3.1.3.2.3 Forwarding to upper layers)
[3.1.3.2.4 Gatewaying on-the-fly](#3.1.3.2.4 Gatewaying on-the-fly)
[3.1.3.2.5 Common requirements](#3.1.3.2.5 Common requirements)
[3.1.3.2.6 All destination transport protocol modules will confirm transmission of the IPDU.](#3.1.3.2.6 All destination transport protocol modules will confirm transmission of the IPDU.)
[3.1.3.3 FIFO](#3.1.3.3 FIFO)
[3.1.3.3.1 Communication Interface](#3.1.3.3.1 Communication Interface)
[3.1.3.3.2 Transport Protocol](#3.1.3.3.2 Transport Protocol)
[3.2 Cancel transmission](#3.2 Cancel transmission)
[3.3 Cancel reception](#3.3 Cancel reception)
[3.4 Zero Cost Operation](#3.4 Zero Cost Operation)
[3.5 State Management](#3.5 State Management)
[3.6 Routing path groups](#3.6 Routing path groups)
[3.7 Complex Drviver Interaction](#3.7 Complex Drviver Interaction)
[4.PDU Router模块和其他模块的交互-以CAN相关模块交互为例](#4.PDU Router模块和其他模块的交互-以CAN相关模块交互为例)
[4.1 CanIf模块的I-PDU接收时序](#4.1 CanIf模块的I-PDU接收时序)
[4.2 CanTp模块的I-PDU接收时序](#4.2 CanTp模块的I-PDU接收时序)
[4.3 CanIf发送I-PDU](#4.3 CanIf发送I-PDU)
[4.4 CanTp发送I-PDU](#4.4 CanTp发送I-PDU)
[4.5 CanIf直接通过PDUR进行网关路由](#4.5 CanIf直接通过PDUR进行网关路由)
1.PDUR模块功能介绍
PDUR模块在AUTOSAR架构中属于通信服务模块。PDU路由模块使用以下模块类型为I-PDU(交互协议数据单元)的路由提供服务。
(1)通讯接口模块,即使用<Provider:Up>或<Provider:Lo>API的模块,如Com, IpduM, LinIf, CanIf, CanNm, Frlf, FrNm
(2)传输协议模块,即使用<Provider:Up>或<Provider:Lo>API的模块,如j1939Tp, LinTp(part of LinIf), CanTp, FrTp, COM, DCM
也就是说,上层模块(Com, DCM, DEM)使用PDUR提供的服务进行路由:
例子: Com -> PDUR ->CanIF
Com -> PDUR -> LinIf
DCM -> PDUR -> CanTp
I-PDU的路由是基于静态定义的I-PDU标识符执行的。没有I-PDU在运行时被动态路由。相关模块可能位于上层(DCM,COM,lpduM)模块和下层模块(CanIf, Frlf, LinTp, lpduM, CanNm, FrNm)模块。lpduM作为上层模块是因为lpduM和COM之间存在通讯,作为下层模块是因为lpduM和其他接口模块(CanIf, Frlf, LinTp, CanNm, FrNm)存在通讯。
PDU路由模块是基于接口模块的通用方法。在PDU路由器模块配置宏配置接口模块。PDU路由模块可以轻松的配置成支持另外的上下层模块。这种方法还允许集成负责驱动(CDD)作为PDU路由模块的上层或者下层模块。
下面列出上层和下层最常见的组合:
. DCM和TP层模块
. COM和通讯接口模块,TP模块或者I-PDU多路复用模块
. I-PDU多路复用模块和通讯接口模块
PDU路由模块是AUTOSAR基础软件的一部分,是AUTOSAR ECU中必须实现的。PDU Router模块主要包含以下两部分:
- PDU Router 路由表:静态的路由表,描述每一个被路由的I-PDU属性。路由表在预编译阶段可配置。
- PDU Router引擎:根据路由表实际执行路由操作。路由引擎必须处理的有:
从源头地路由I-PDU到目的地
将源I-PDU ID转换到目的(例如从PduR_Transmit到CanIf_Transmit, 从PduR_CanIfTxConfirmation到Com_TxConfirmation)
I-PDUs由静态的I-PDU ID标识。PDU Router模块通过使用静态配置表里面的I-PDU ID确定每一个I-PDU的目的地。I-PDUs用于PDU Router的上层模块之间的数据交换,例如COM模块和DCM模块。PDU Router模块不会修改I-PDU的内容,只是简单的将I-PDU传输到目的模块。
I-PDU ID是在实现API的配置中设置的,这将允许在每个接收I-PDU ID的模块中有效地实现查找表(例如,PDU路由表的配置包含PduR_CanIfTxConfirmation的I-PDU ID)。
PDU路由模块支持的路由方式:
. 单播(1:1):一个I-PDU从一个本地模块到一个通信接口模块,例如COM-->CanIf
. 组播(1:n):一个I-PDU从一个本地模块到多个通信接口模块,例如COM-->CanIf, LinIf
. 单播(1:1):一个单帧SF I-PDU(单帧,SF:传输层帧类型概念,后面文章讲解)或者多帧(首帧 + 连续帧)从一个模块到一个传输层模块,例如DCM--> CanTp
.组播(1:n):一个单帧(SF)从本地模块到多个传输层模块。例如DCM-->CanTp, LinTp
.单播(1:1):一个I-PDU从通信接口模块到一个上层本地模块。例如CanIf-->Com
.组播(1:n):一个I-PDU从通信模块到多个上层本地模块。
.单播(1:1):一个I-PDU(单帧SF)从一个传输层模块到上层模块。例如CanTp-->DCM
.组播(1:n):一个I-PDU(单帧SF)从传输层到多个上层模块。
.网关(1:1):使用last-is-best buffer把一个I-PDU从一个通信接口模块传输到另一个通信接口模块。
.网关(1:n):使用last-is-best buffer把一个I-PDU从一个通信接口模块传输到多个通信接口模块。
.网关(1:1):使用FIFO把一个I-PDU从一个通信接口模块传输到另一个通信接口模块。
.网关(1:n):使用FIFO把一个I-PDU从一个通信接口模块传输到多个通信接口模块。
.网关(n:1):使用FIFO把一个I-PDU从多个通信接口模块传输到一个通信接口模块。
.网关(1:1):使用FIFO把一个I-PDU从要给传输层模块传输到另一个传输层模块。
.网关(1:n):使用FIFO把一个I-PDU从要给传输层模块传输到多个传输层模块。
.网关(n:1):使用FIFO把一个I-PDU从多个传输层模块传输到一传输层模块。
网络管理的数据交换绕过PDU Router模块。
PDU路由器模块依赖于使用的通信硬件抽象层模块和使用的通信服务层模块的API和能力。PDU Router模块基本需要的API功能有:
通信接口门口:
<Lo>_Transmit (e.g. CanIf_Transmit, FrIf_Transmit, LinIf_Transmit)
<Lo>_CancelTransmit (e.g. CanIf_CancelTransmit, FrIf_CancelTransmit,
LinIf_CancelTransmit)
传输层模块:
· <LoTp>_Transmit (e.g. CanTp_Transmit, FrTp_Transmit, LinTp_Transmit)
<LoTp>_CancelTransmit(e.g.CanTp_CancelTransmit,FrTp_CancelTransmit,LinTp_CancelTransmit) ·
<LoTp>_CancelReceive(e.g.CanTp_CancelReceive,FrTp_CancelReceive,LinTp_CancelReceive)
使用TP传输层的上层模块:
· <Up>_StartOfReception (e.g. Dcm_StartOfReception)
· <Up>_CopyRxData (e.g. Dcm_CopyRxData)
· <Up>_CopyTxData (e.g. Dcm_CopyTxData)
· <Up>_TpRxIndication (e.g. Dcm_TpRxIndication)
· <Up>_TpTxConfirmation (e.g. Dcm_TpTxConfirmation)
处理通信接口模块产生的I-PDU的上层模块:
· <Up>_RxIndication (e.g. Com_RxIndication),
· <Up>_TxConfirmation (e.g. Com_TxConfirmation),
· <Up>_TriggerTransmit (e.g. Com_TriggerTransmit)
2.关键概念理解
Upper Layer Modulses(Up): PDU Router之上的模块。通常指是COM和DCM模块。
Lower Layer Modulse(Lo): PDU Router之下的模块。包括CanIf, LinIf, FlexRayIf, EthIf以及这几个模块对应的TP传输层模块。
PDU Router: PDUR模块将I-PDUs从一个模块传输到另一个模块。
Gatewaying-on-the-fly: 网关功能,两个TP模块之间的路由,在所有数据都收到之前开始转发数据(当达到指定的阈值时)。如果在两个接口之间传输大量的数据,则希望能够在从源网络接收所有数据之前在目标网络上开始传输。这样可以节省内存和时间。
Multicast operation: 同时发送pdu到一组接收器,即1:n路由。
Data provision: 为接口模块提供数据。
(a)直接提供数据:根据发送请求直接提供要传输的数据。目标通信接口可以有两种行为,要么直接复制数据,要么将复制延迟到触发器传输。
(b)触发发送数据提供:在发送请求时不提供要发送的数据,由接口模块通过回调函数检索
Last-is-best-buffering: 最新值覆盖上一个值的缓冲策略。
FIFO Bufferfing: 先进先出的缓冲策略。
3.功能详细设计
从ECU的视角来看,PDU Router模块能够进行三种不同类型的操作:
. 从本地模块接收PDU:从底层模块接收I-PDU并将他们转发到一个或多个上层模块
. 从本地模块传输PDU:上层模块请求传输I-PDU到一个或多个底层模块
. PDU网关:
. 从一个接口模块接收I-PDU,然后通过相同或者另外的通讯接口模块立即传输I-PDU
. 从一个传输层模块接收I-PDU,然后通过相同或者其他的传输层传输I-PDU
PDU Router模块可以实现PDU接收和PDU网关的组合功能。例如:COM模块接收一个I-PDU,同时它被网关传送到另一个较低的单元层模块。
3.1I-PDU handling
每一个I-PDU都被I-PDU ID标识。
每个处理I-PDU以及提供关于I-PDU API的BSW模块都包含一个I-PDU ID的表,这就意味着每个被调用的模块都有一个标识I-PDU的查找表。
示例:COM模块调用PduR_ComTransmit(在这种情况下,PDU Router模块会列出I-PDU ID表),PDU Router模块调用CanIf_Transmit(这种情况下,CanIf模块的配置中将会列出I-PDU ID),CanIf模块调用PduR_CanIfTxConfirmation(这种情况下,PDU Router模块配置中将会列出I-PDU ID表),PDU Router模块调用Com_TxConfirmation(这种情况下,COM模块的配置表中将会列出I-PDU ID表)。
PDU Router模块通过源模块I-PDU ID(位于PDU Router配置中)和目的模块I-PDU ID(位于所谓的目的模块配置中)的组合来唯一标识路由路径。
PDU路由器模块应将I-PDU ID转换为传输路径和确认/指示路径的目的模块。
示例:COM模块向CanIf和LinIf发送I-PDU。调用PduR_ComTransmit。PDU Router模块将源I-PDU ID (PDU Router模块配置)转换为LinIf的一个I-PDU ID (LinIf模块配置)和CanIf的一个I-PDU ID (CanIf模块配置)。从COM模块接收到的PduInfoType值会复制到CanIf和LinIf模块中,不做任何修改。
示例:Linif将使用I-PDU ID调用PduR_LinIfTxConfirmation,并根据传输成功调用结果E_OK(传输成功)或E_NOT_OK(传输不成功)。然后,PDU路由器模块将转换这个I-PDU ID,并使用Com_TxConfirmation将调用转发给COM,其中包含转换后的I-PDU ID和接收到的结果。
3.1.1 I-PDU Reception to upper module(s)
PDU路由器模块的接收操作总是由来自底层模块(通信接口模块或传输协议模块)的指示(PduR_<Lo>RxIndication或PduR_<LoTp>RxIndication)完成。回调Indicaiton函数由底层模块在轮询通讯驱动程序的循环函数中执行,或者中断的上下文中执行。
3.1.1.1 Communication Interface
通讯接口模块通过调用PduR_<Lo>RxIndication函数来指示标识接收到了I-PDU。每个I-PDU在路由表上可能被配置为多个模块接收。
当PduR_<Lo>RxIndication被底层模块调用后,PDU Router模块将会调用<Up>_RxIndication通知到该I-PDU的每一个目的上层模块。
当本地Can, Lin, 等通信模块接收到数据后,PDU Router模块不会检查数据的长度信息,直接通知到对应的上层模块。
3.1.1.2 Transport Protocol
当下层为传输层模块的时候,PDU Router模块在传输层收到首帧或者单帧的时候被第一次通知。PDU Router模块调用<Up>_StartOfReception通知到上层模块。目的上层模块中调用<Lo>_CopyRxDat接口接收随后的连续帧N-PDU。传输层接收到最后一个N-PDU后将会通知PDU Router模块完成了本次I-PDU的接收,同时PDU Router模块将会调用<Up>_TpRxIndication转发这次通知到上层模块。
通过传输层接收的I-PDU在路由表中可能只有由一个上层模块。
3.1.2 I-PDU Transmission from upper module(s)
对目标底层模块的传输操作始终是异步的。这就意味着PDU Router模块将I-PDU传递到目的底层模块之后,传输服务请求立即返回。底层模块在I-PDU被传输后调用PduR_<Lo>TxConfirmation(communication interface)或者PduR_<LoTp>TxConfirmation(transport protocol)通知到PDU Router模块,同时RDU Router模块通过<Up>_TxConfirmation(communication interface)或者<Up>_TpTxConfirmation(transport protocol)转发这个通知到上层模块。
PDU Router模块的传输操作由上层模块的传输请求触发,同时PDU Router模块转发请求到下层模块。数据传输过程中PDU Router模块不会缓存I-PDU。
3.1.2.1 Multicast
组播传输请求下(1:n)如果有一个目标传输请求返回成功的话,PduR_<Up>Transmit将会返回E_OK。返回E_OK的通信接口将直接或通过触发器传输传输它们的数据。
其他传输协议模块可能返回E_NOT_OK,因此这些模块不会调用PduR_<LoTp>CopyTxData。由于源上层模块已被告知至少一次传输成功,因此至少有一个传输协议模块将调用PduR_<LoTp>CopyTxData。
如果一个传输请求中存在多个底层目标模块(1:n, n>1),则所有这些模块都必须是通信接口模块或传输协议模块。不是它们的混合。例如:上述要求基本上是指COM模块不能请求传输,然后PDU Router模块使用同一个I-PDU将传输路由到CanTp模块和CanIf模块。
对于组播(1:n, n>1)通信接口传输,当收到支持发送确认的通信接口模块的最后一次发送确认时,PDU路由器应调用上层模块的发送确认API。实现说明:当源模块请求传输时,PduR组播(1:n, n>1),请求中的所有I-PDU和组播中的所有I-PDU id都不同。因此,PduR必须记住传输请求中的I-PDU ID,才能正确确认传输。
3.1.2.2 Communication Interface
I-PDUs在通讯接口上有三种传输方式:
-
Direct data provision:上层模块调用PduR_<Up>Transmit 函数,PDU Router模块调用<Lo>_Transmit转发这个请求,同时底层通讯接口模块拷贝数据
-
Trigger transmit data provision: 底层通讯接口模块调用PduR_<Lo>TriggerTransmit请求数据传输,PDU Router通过PduR_<Up>TriggerTransmit转发这个请求到上层模块,在上层模块完成数据的拷贝。
-
上层模块调用PduR_<Up>Transmit 函数,PDU Router模块调用<Lo>Transmit转发这个请求,同时底层通讯接口模块不拷贝数据。底层模块之后使用PduR<Lo>TriggerTransmit请求数据。
直接数据传输和触发式数据传输的传输确认方式是一样的。
3.1.2.2.1 Trigger transmit data provision
上层模块必须被告知是否需要重置更新位,并以正确的方式处理I-PDU计数器。
3.1.2.3 Transport Protocol
使用传输协议传输I-PDU有单播和组播两种方式。单播(1:1)传输由一个源上层模块和一个目的下层传输协议模块组成。一个组播(1:n, n>1)传输由多个目的地较低层传输协议模块组成。PDU Router模块不检查传输请求中是否包含单个NPDU (SF)或多个N-PDU (FF, CF,...)。
上层模块调用PduR_<Up>Transmit开始传输数据。PduR将根据路由路径使用<Lo >_transmit将请求转发到一个或多个目的地较低层传输协议模块。注意,<Lo>_Transmit可能包含也可能不包含数据。
目标模块将通过调用PduR_<LoTp>CopyTxData请求数据。数据的重传(如果传输协议支持)由RetryInfoType参数决定。完成传输后,目的模块调用PduR_<LoTp>TxConfirmation,该PduR_<LoTp>TxConfirmation被转发给源上层模块。
3.1.2.3.1Multicast transmission
由于1:n, n>1路由是在PDU Router模块中进行的,所以PDU Router模块必须多次向源上层模块请求相同的数据。此外,必须特别处理对多播的确认。
由于上层需要多次复制相同的数据,所以PDU路由器会使用RetryInfoPtr来多次查询相同的数据。RetryInfoPtr包含一个名为TpDataState的状态类型。
组播传输过程中,第一个目的低层模块的PduR_<LoTP>CopyTxData的请求需要将TpDataState参数设置为TP_CONFPENDING状态后进行转发。
PduR_<LoTp>CopyTxData请求的所有后续调用都必须通过TP_DATARETRY转发,以允许复制相同的数据。
在所有传输协议收到它们的数据后,PDU路由器模块可以向上层模块确认数据。
在多播传输时,PDU路由器模块从下层传输协议模块接收到最后一个PduR_<LoTp>TxConfirmation后,使用<Up>TpTxConfirmation调用上层模块。如果至少有一个PduR<LoTp>TxConfirmation报告了E_OK,则'result'参数应该是E_OK。
3.1.3 I-PDU Gateway
PDU路由模块支持I-PDU从一个源总线到一个或多个目的总线的网关功能。网关功能和本地模块接收或者发送功能不同的是路由模块必须同时是一个发送者和接收者,在一些情况下还需要给I-PDU提供缓存。
网关需求被故意剥离开,以允许在不需要网关的情况下有效地实现PDU路由模块。如果PDU路由模块允许I-PDU网关,网关功能被视为附加的功能而不是取代以前的收发功能。
网关功能概要:
(1)I-PDU可以从一个源通信接口模块网关路由到一个(1:1)或多个目的通信接口模块(1:n I-PDU网关)。
-- 对于每个目的地,PDU Router模块可以为每个目的模块接收的每个I-PDU配置缓存(即如果有多个I-PDU,则为FIFO)。
-- I-PDU可以在网关到n个目的通信接口的同时被上层模块接收。
(2)使用TP传输的I-PDU可能被网关到一个或多个目的地TP模块,范围如下:
-- 单帧和多帧都可以网关到一个以上的目的地TP模块或本地模块(例如DCM)。
-- 在多个N- PDU中传输的I-PDU可能会被"动态"网关到一个目的地,这意味着在目的地TP模块开始传输之前不需要收到完整的I-PDU
-- 在多个n - pdu中传输的I-PDU可能被网关到另一个TP模块或被本地模块接收,而不是同时被接收。
-- 使用TP模块传输的pdu可以被FIFO缓冲。这适用于SF和多帧I-PDU。
I-PDU只能在通信接口模块和TP模块之间网关,不能混用。例如,无法从CanIf接收到I-PDU并将其网关给LinTp。
这意味着PDU Router模块应将从底层模块(源网络)接收到的I-PDU转发给由所提供的I-PDU ID标识的底层模块(目的网络)。
3.1.3.1 Communication interface modules
一个I-PDU可以配置为在一个通信接口模块上接收,并网关到n个通信接口模块(包括本地模块),即1:n个网关。对于网关,也可以为每个目的地通信接口模块配置一个FIFO(但不是本地模块)。
PDU Router模块支持I-PDU在具有即时传输(不由PDU Router产生速率)的通信接口模块之间的路由。
不支持在不同周期或速率(速率转换)的通信接口模块之间路由I-PDU,这可以通过使用信号网关通过COM模块来完成。在这种情况下,I-PDU必须路由到COM模块。
根据目的接口模块的不同,有两种类型的I-PDU网关。使用类型由配置控制:
-- Direct data provision:目的I-PDU的pdurdestpudataprovision配置为PDUR_DIRECT。当<DstLo >_transmit被调用时,<DstLo>模块复制数据,PDU路由器不再缓存传输的I-PDU
--Trigger transmit data provision:目的I-PDU的pdurdestpudataprovision配置为PDUR_TRIGGERTRANSMIT。当<DstLo >transmit被调用时,<DstLo>模块不会复制数据,PDU Router模块将缓冲I-PDU并等待<DstLo>模块的PduR<DstLo>TriggerTransmit调用
在last-is best buffering(参见PduRQueueDepth)的情况下,PduRouter将缓冲最新的I-PDU,以防触发传输数据供应。
触发式数据传输时必须存储I-PDU的原因是目的通信接口可以按照时间表发送I-PDU。然后通信接口将调用PduR_<DstLo>TriggerTransmit,而不需要前面的<DstLo>_Transmit调用。
如果使用FIFO- buffer(参见PduRQueueDepth),如果目的通信接口模块使用PduR_<DstLo>TriggerTransmit请求I-PDU缓冲区,并且FIFO为空,则返回E_NOT_OK。
如果目的通信接口模块使用PduR_<DstLo>TxConfirmation确认I-PDU的传输(成功或失败),并且目的地不是一个具有FIFO缓冲区的直接数据提供的Pdu, Pdu路由器模块将不做任何事情。
将被网关的I-PDU可能有不同的长度。因此:
如果I-PDU在PDU Router中没有缓存,则PDU Router无需检查就转发长度,只调用目的模块的发送功能。
如果I-PDU在PDU Router模块中被缓存:PDU Router模块将I-PDU的数据复制到以下最小值:
--接收到的数据长度(PduLength of received I-Pdu)
--配置的缓冲区中最大PduLength (PduRPduMaxLength)。在这种情况下,接收到的I-PDU的其余部分将被丢弃。
当PduR_<Lo>TriggerTransmit被调用时,为用户提供避免缓冲区溢出的可能性。用户需要配置PduRMaxPduLength不大于目的I-Pdu的长度。
当I-PDU从PduR缓冲区传输(直接提供数据)到目标模块时,PduR将复制到缓冲区的字节数作为SduLength传递。
当I-PDU从PduR缓冲区复制(触发传输数据提供)到目标模块时,PduR应检查下层缓冲区的大小,即SduLength。如果缓冲区对于存储的PDU数据来说太小,PduR将返回E_NOT_OK,不再处理TriggerTransmit调用。
3.1.3.2 Transport Protocol
网关路由I-PDU从一个传输层到另外的一个或者多个传输层模块有两种方式,一种是网关路由传输完整的I-PDU(首帧SF加连续帧CF),也就是在传输I-PDU之前完整的I-PDU已经被接收到了;另一种就是动态网路由分赛的I-PDU,在路由传输I-PDU之前,I-PDU的数据长度先被目的传输层模块接收到了。
一般来说,PDU Router只会对负载进行网关,而不会知道传输协议的细节,如SF、FF、CF、PCI等。但是PduR也应该支持带有元数据的I-PDU的网关,使用全局PDU的MetaDataType进行配置。这种类型的I-PDU在接口路由或转发时不需要进行特殊处理,但对于TP路由,额外的信息需要单独转发。以下要求对于直接网关和动态网关都是相关的:
PduR_<SrcLoTp>StartOfReception提供的I-PDU元数据需要存储并提供到<DstLoTp>_Transmit的I-PDU
在传输协议模块中,一个I-PDU可以在多个N-PDU (FF、cf)中传输,也可以在单个N-PDU (SF)中传输。一个用例是,在多个N-PDU中传输的I-PDU不是组播(即物理寻址),而在单个N-PDU中可能是组播(即功能寻址)。另一个用例是多帧消息多播到本地接收器和多个网关目的地。
例如:在CAN上接收一个SF,需要在两条LIN总线上传输。接收到的SF最多可以携带6字节的数据,但是LIN上的SF最多只能携带5字节的数据。因此,如果网关到两个LIN总线,CAN上的SF被限制为5字节的数据。
注意,通过传输协议模块传输的I-PDU也可以通过通信接口一帧接一帧地网关(即直接网关n - pdu)。这里不需要对PDU Router模块进行特殊处理,可以通过通信接口模块通过网关进行处理。然而,这要求源和目的总线具有完全相同的n - pdu封装(例如,从CAN到CAN)。
3.1.3.2.1 Buffer allocation
PduR使用两个不同的缓冲区作为传输协议pdu的网关:通过PduRRoutingPaths配置的大TP缓冲区池,以及通过PduRDestTxBufferRef配置的专用缓冲区。专用缓冲区用于单帧路由,必须足够大,以包含所涉及的总线系统的最大可能的单帧。大的PduRTpBuffers用于多帧路由,在动态网关中必须大到足以包含一个TP数据块,在直接网关中必须大到足以包含完整的PDU。为单个帧使用专用缓冲区的主要原因是功能性诊断请求,特别是OBD请求具有非常高的优先级,不能被缓冲区分配策略所延迟。
如果通过PduR_<SrcLoTp>StartOfReception表示网关的TP PDU接收,且TpSduLength参数报告的总SDU大小不大于PduRDestTxBufferRef所引用的专用缓冲区的配置PduRPduMaxLength,则PduR将使用该专用缓冲区。
如果通过PduR_<SrcLoTp>StartOfReception表示网关的TP PDU接收,而TpSduLength参数报告的SDU总大小大于专用缓冲区配置的PduRPduMaxLength,则PduR需要从PduRTxBuffer中动态分配一个缓冲区。
如果在调用PduR_<SrcLoTp>StartOfReception接收网关TP PDU的过程中无法分配缓冲区,则PduR将立即停止对该I-PDU的进一步处理并返回BUFREQ_E_OVFL。
对于TP网关场景,PduR_<LoTp>CopyTxData的availableDataPtr表示PduR_<LoTp>CopyTxData的剩余可用字节数。
3.1.3.2.2 Direct gatewaying
如果结果是E_OK,则在PduR_<SrcLoTp>TpRxIndication中的每个目的地传输协议模块上调用<DstLoTp >_transmit
对于单帧传输,如果使用TpDataState TP_CONFPENDING或TP_DATACONF调用PduR_<DstLoTp>CopyTxData,或者当RetryInfoType指针为NULL时,PDU路由器需要复制SduLength字节的数据。如果没有足够的数据可用,Pdu路由器将返回BUFREQ_E_BUSY,而不复制任何数据。
对于单帧传输,如果使用TpDataState TP_DATARETRY调用PduR_<DstLoTp>CopyTxData,则PDU路由器将通过TxTpDataCnt字节将当前位置置回,并复制数据的SduLength字节。如果Pdu路由器不能按照请求设置位置,它应该返回BUFREQ_E_NOT_OK,而不改变当前位置或复制任何数据。如果重置当前位置后,没有足够的数据可以复制,则Pdu路由器应返回BUFREQ_E_BUSY,而不进行复制。
对于多帧传输,如果使用TpDataState TP_CONFPENDING或TP_DATACONF调用PduR_<DstLoTp>CopyTxData,或者当RetryInfoType指针为NULL时,PDU路由器需要复制SduLength字节的数据。只有来自最后一个目的地模块的调用才会增加缓冲区位置。
如果没有足够的数据可用,或者不是所有其他的目的传输协议模块都为前一帧调用了PduR_<DstLoTp>CopyTxData, Pdu路由器将返回BUFREQ_E_BUSY而不复制任何数据。
对于多帧传输,如果使用TpDataState TP_DATARETRY调用PduR_<DstLoTp>CopyTxData,则PDU路由器将返回BUFREQ_E_NOT_OK,而不复制任何数据。
3.1.3.2.3 Forwarding to upper layers
如果I-PDU通过网关(直接传输协议网关)到达一个或多个目的地传输协议模块,则该I-PDU也可能被本地上层模块接收。
实现可以选择在上层接收不成功时报告(通过DET)。在这种情况下,不应该中止到较低层次的网关。
直接网关上层部分的接收方式如下:
在网关的情况下,当PduR从下层成功接收到RxIndication时,模块应启动一个已配置的上层目的地的接收会话:<UpTp>_StartOfReception,<UpTp>_CopyRxData, <UpTp>_RxIndication将按此顺序调用。
当<UpTp >_startofreception对配置本地目的的组播TP网关返回错误时,PduR应停止上层接收,不再与上层交互。
当<UpTp>_StartOfReception返回BUFREQ_OK,但可用缓冲区太小,无法接收整个消息时,PduR调用<UpTp>_RxIndication,结果= E_NOT_OK
当<UpTp>_CopyRxData返回错误时,PduR将调用<UpTp>_RxIndication并返回result = E_NOT_OK
3.1.3.2.4 Gatewaying on-the-fly
在动态网关中,当达到特定的阈值时,PDU路由器模块将开始向目的地传输协议模块发送数据。
使用动态网关只允许一个目的地传输协议模块。
一旦到达特定目的地的Tx阈值,PDU路由器模块将通过调用<DstLoTp >_transmit在目的总线上启动TP传输。
如果通过PduR_<SrcLo>StartOfReception启动TP传输,当PduRTpThreshold = 0时,PDU Router模块直接调用<DstLoTp>_Transmit。
如果使用动态网关,则Pdu路由器不支持对已传输数据的重传:
如果PduR_<SrcLoTp>RxIndication的结果值为E_OK,即使没有达到TP的阈值,PDU Router模块也应该通过调用<DstLoTp >_transmit在目的总线上启动TP传输。
如果PduR_<DstLoTp>CopyTxData被TpDataState TP_DATACONF调用,或者如果RetryInfoType指针为NULL, PDU路由器将复制SduLength字节的数据。
3.1.3.2.5 Common requirements
以下要求适用于直连网关和动态路由网关。
如果PduR_<DstLoTp>CopyTxData被调用,并且state为TP_DATACONF,则PDU路由器可以释放已经复制的数据。
3.1.3.2.6 All destination transport protocol modules will confirm transmission of the IPDU.
当PDU路由器模块收到PduR_<DstLoTp>TxConfirmation时,PDU路由器将释放I-PDU缓冲区。
如果传输协议模块调用长度为0的PduR_<LoTp>CopyTxData或PduR_<LoTp>CopyRxData (PduInfoType. conf . conf)。SduLength = 0) PDU路由器模块应分别返回当前可用缓冲区的大小或当前可用数据的大小。
3.1.3.3 FIFO
使用FIFO队列行为从一个源到多个目标的底层模块可以网关一个I-PDU。FIFO队列可以用于通信接口和传输协议(即使有多个N-PDU消息)
如果PduRQueueDepth配置为大于1的值,则发送Pdu缓冲区将具有先进先出(FIFO)行为。
FIFO有状态,当从不同的上下文调用不同的PduR API时,这些状态可能会改变。例如,PduR_<SrcLo>RxIndication呼叫可能会被PduR_<DstLo>TxConfirmation呼叫中断。因此有必要保护那些并发调用。
如果在直接提供数据的情况下使用FIFO,目的I-PDU必须配置为调用PduR_<DstLo/DstLoTp>TxConfirmation,请参见PduRTransmissionConfirmation。
应该可以为每个目的地配置一个FIFO PDU.
如果直接数据提供与FIFO一起使用:当PduR_<SrcLo/SrcLoTp>RxIndication被调用,并且相同PDU的最后一次传输尚未通过PduR_<DstLo/DstLoTp >TxConfirmation被确认时,PduR将在FIFO中排队新数据。
如果与FIFO一起使用直接数据提供:当PduR_<SrcLo/SrcLoTp>RxIndication被调用,且FIFO队列为空,且同一PDU没有未确认的情况下,<DstLo/DstLoTp> _transmiting应被直接调用。FIFO是空的
当PduR_<SrcLo/SrcLo>RxIndication被调用,并且在触发发送数据提供的情况下FIFO队列是空的,接收到的I-PDU将被复制到FIFO,并调用<DstLo/DstLoTp >_Transmit
当PduR_<SrcLo/SrcLoTp>RxIndication被调用,并且FIFO队列不是空的时候,接收到的I-PDU应该作为最新的条目被复制。
当PduR_<DstLo/DstLoTp>TxConfirmation被调用,并且在直接提供数据的情况下FIFO队列不是空的,<DstLo/DstLoTp>_Transmit应该被调用FIFO最古老的I-PDU。传输的I-PDU随后将被移除。
3.1.3.3.1 Communication Interface
当调用PduR_<DstLo>TriggerTransmit并根据SWS_PduR_00819返回E_OK时,需要将最老的FIFO项复制并删除。如果之后FIFO队列不是空的,<DstLo>_Transmit将被FIFO最古老的I-PDU调用。
注意:如果目的模块是FrIf,则需要将Pdu的FrIfCounterLimit配置为> 1,因为新的传输将在计数器减少之前被调用。对于LinIf没有这样的约束,但是FIFO队列路由到零星帧是不支持的。
3.1.3.3.2 Transport Protocol
当PduR_<SrcLoTp>StartOfReception和FIFO被启用时,PduR应该从PduRTxBuffer中保留足够的缓冲区(对于每个目的地在1:n的情况下)
当PduRTpThreshold或者PduR_<DstLoTp>RxIndication被称为)I-PDU被接收到时,PduR将在目的传输协议上开始传输。
如果调用相同路由路径的另一个PduR_<SrcLoTp>StartOfReception,则PduR将I-PDU存储在FIFO中。
当从目的传输协议模块接收到PduR_<DstLoTp>TxConfirmation时,如果FIFO不为空,PduR将开始发送下一个IPDU。
允许在网关上使用动态路由。如果FIFO队列为空,则PduR可以在每次达到PduRTpThreshold时调用<DstLoTp >_transmit。
如果FIFO队列已经包含了至少一个条目,接收到的消息将被存储在FIFO中,并且<DstLoTp >_transmit将在该FIFO队列条目即将传输时被调用(即当此消息第一次进入FIFO时)。
注意:使用FIFO的动态网关的效果是,它将是一种更快的网关TP消息的方法。显然,如果FIFO不是空的,那么接收到的消息必须被存储,而不是被转发到目的TP。
3.2 Cancel transmission
上层模块可以请求取消I-PDU(由通信接口模块或传输协议模块传输)。PDU路由器模块将请求转发给一个目标模块(单播)或多个目标模块(多播)。
PduR_<Up>CancelTransmit用于取消通信接口I-PDU,转发时取消传输协议I-PDU。
取消传输是可选的,并在每个模块的配置中启用,参见PduRCancelTransmit配置参数。
转发时,上层模块请求取消I-PDU, PDU路由器根据路由路径将请求转发给一个或多个目的模块。
在网关的情况下,取消传输可以被PduR的网关部分用来优化资源处理(例如,如果目的地不再可用)。
3.3 Cancel reception
上层模块可以请求取消在传输协议模块上传输的I-PDU。PDU路由器模块将通过PduR_<Up>CancelReceive接收请求。取消请求的确认是通过<LoTp>CancelReceive的返回值进行的,该返回值作为PduR<Up>CancelReceive的返回值转发给上层模块。
3 . 4 Zero Cost Operation
使用Zero Cost Operation ,则PDUR Router变成一个宏层,在单个源到单个目的情况下使用。例如项目中只用到了一路CAN。则PduR_ComTransmit直接调用CanIf_Transmit。
3.5 State Management
PDU Router模块有两个状态:
PDUR_UNITIT: ECU上电后进入PDUR_UNITIT,不执行路由网关功能。
PDUR_ONLINE: 系统调用PduR_Init()函数后进入PDUR_ONLINE状态,执行路由网关功能。
3.6 Routing path groups
路由路径组是一组I-PDU,可以在运行时禁用或启用。组包含目的I-PDU,不包含路由路径本身。原因是需要为特定总线启用或禁用I-PDU。一个路由路径可以将一个I-PDU多播到几个总线。
启用和禁用路由路径组通常由BswM模块使用。
3.7 Complex Drviver Interaction
复杂驱动CDD可以作用PDU Router模块的上层或者底层模块使用PDU Router功能。
4.PDU Router模块和其他模块的交互-以CAN相关模块交互为例
4.1 CanIf模块的I-PDU接收时序
CANDrv模块接收到数据后调用通知到CanIf模块,CanIf调用PduR_<User:Lo>RxIndication()函数通知到PduR模块并传递I-PDU数据指针PduInfoType*,PDUR模块调用Com_RxIndication()函数通知到COM模块,COM通过PduInfoType*指针完成接收数据的拷贝。
4.2 CanTp模块的I-PDU接收时序
4.3 CanIf发送I-PDU
Com模块调用Pdur_ComTransmit()函数发送I-PDU,Pdur模块调用CanIf_Transmit()函数发送I-PDU。发送成功后,CanIf调用Pdur_ComTxComfirmation()函数通知Pdur发送成功,Pdur调用Com_TxComfirmation()函数通知Com模块I-PDU发送成功。
4.4 CanTp发送I-PDU
4.5 CanIf直接通过PDUR进行网关路由
5.PDUR模块配置简介
PDUR模块主要包括PduRBswModules,PduRGeneral, PduRRoutingPaths三个主要配置。
PduRBswModules: 配置需要使用PDUR路由功能的上下层BSW模块。
PduRGeneral: 配置PDUR模块的通用功能。
PduRRoutingPaths:配置I-PDU的路由表。
本章简要介绍PduR模块的几个重要配置项,具体的实际操作留意后续结合实际具体项目的实战文章。
5.1PduRBswModules配置
PduRBswModules配置需要使用PDUR路由功能的上下层BSW模块。
配置的主要参数为:
PduRCancelReceive:传输层模块是否支持CancelReceive功能
PduRCancelTransmit:BSW模块是否支持CancelTransmit功能
...
以下的每个参数都是配置BSW模块是否支持某个对应的功能,具体的功能可以参考上文的功能详细设计部分。
5.2PduRGeneral配置
配PDU Router模块的一些通用功能。
例举几个重要的配置功能:
PduRIFGatewayOperation: 配置是否支持从一个底层Interface模块到底层另一个Interface模块的网关路由。
PduRZeroCostOperation: 配置是否支持Zero Cost Operation功能。
PduRTPGatewayOperation: 配置是否支持传输层模块之间的路由功能。
5.3PduRRoutingPaths配置
PduRRoutingPaths包含PduRRoutingPathGroup, PduRRoutingTables,PduRTpBufferTable,PduRTxBufferTable四个子container配置。
其中最重要的配置是PduRRoutingTables,配置每一个I-PDU的路由路径,也就是从上层哪一个模块发送到下层哪一个模块,以及下层接收的I-PDU路由到哪一个上层模块。