1、概述
1.1、基本概念
PDUR路由单元在整个AUTOSAR的位置如下图
PDUR在整个通信里面的位置信息如下,从下面这张图可以看出PDUR能将I-PDU传递到不同的AUTOSAR组件。说白一点就是:PduR模块从CANIf模块/COM模块接收到了PDU ,然后根据PDU ID查找已定义好的静态路由表,获得其目标地址,定向并转发到COM模块/CANIf模块的操作。
解释名词<I-PDU>: 交互层协议数据单元,I-PDU由数据(缓冲区)、长度和I-PDU ID组成。pdu路由器主要是路由I-PDUs
解释名词<路由>:从一个接口收到数据包,根据数据包的目的地址定向转发到另一个接口的动作。
PduR模块主要提供两方面的服务:
一是承上启下衔接上层和下层:发送时派发从高层模块的PDU到低层模块;接收时派发从底层模块如If或者TP接收的PDU给高层模块(COM, PduR)。
二是通信网络中的网关功能。其中网关功能有两种:从一个接口层到另外一个相同或者不同总线类型的接口层;从一个TP到另外一个相同或者不同总线类型的TP层。其中路由协议是基于一个静态的路由表和PDU ID的概念。
PDUR的上层包含:DCM\COM\IpduM等
PDUR的下层包含:CanTp\CanIf\NM\IpduM等
为什么包含了两个IpduM呢?IpduM具有两个角色,分别作用于上下层,作用上层时与COM模块通信,作用下层时与CanIf通信。
PduR模块同级的I-PDU多路复用器(IpduM) 模块,它提供对多路复用I-PDU的支持。当IpduM调用PduR模块来传输复用的I-PDU时,或当PduR模块调用它来接收或传输复用的I-PDU确认时,或者当它通过触发器传输来提供数据时, IpduM都被认为是一个上层模块。IpduM调用PduR模块,提出传输确认或接收指示上层(例如COM),或当它被称为PduR模块更新I-PDU时,属于多路复用I-PDU,则被视为下层模块。
1.2、内部组成
从上图可以看出PDUR组成部分只有两个,PDUR路由表、PDUR引擎。
PDUR路由表:此项体现在配置工具里面,属于静态配置,描述I-PDU的路由属性,包含源地址路由到目的地址等信息。
PDUR引擎:此项体现在代码里,根据PDUR路由表执行动作的具体实现代码,属于静态代码的一种体现。PDUR引擎从源模块的PDU ID路由到目的模块的PDU ID,注意一种情况,当多帧传输CANTP使用时,TP的PDU很大,此时需要拆分成很多I-PDU进行传输,在PDUR收到全部的TP PDU之后才开始转发PDU,此时会用到buffer。
PDUR引擎代码体现举例:
PduR_transmission转换为canif_transmission , PduR_CanIfTxConfirmation转换为Com_TxConfirmation
2、功能SPEC
从ECU的角度来看,PDUR可以执行三个类别的操作
1、接收I-PDU到局部模块:局部模块个人理解一般指DCM\COM等,规范解读是从一个下层模块路由到其他一个或多个上层模块。(此描述是从下层到上层)
2、从局部模块传输,局部模块包含上层例如DCM,个人理解上也应该包含下层例如CanIf,规范解读是上层请求传输I-PDU到一个或多个下层。
3、网关功能
接收:xx_If 到xx_If / xx_Tp到 xx_Tp,注意是同层之间的传递,没有跨越上下层。
2.1、与其他模块的依赖
PDU Router模块取决于所使用的通信硬件抽象层模块和所使用的通信服务层模块的API和能力。PDU Router模块所需的API功能主要有:
Xx_If接口模块
<Lo>_Transmit (e.g. CanIf_Transmit, FrIf_Transmit, LinIf_Transmit)
<Lo>_CancelTransmit (e.g. CanIf_CancelTransmit, FrIf_CancelTransmit,LinIf_CancelTransmit)
Xx_TP协议
<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)
<LoTp>_ChangeParameter (e.g. CanTp_ChangeParameter,FrTp_ChangeParameter,LinTp_ChangeParameter) 此处更改为BS与STmin参数,上述TP文章有介绍。
上层用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)
上层用If模块的接口
<Up>_RxIndication (e.g. Com_RxIndication)
<Up>_TxConfirmation (e.g. Com_TxConfirmation)
<Up>_TriggerTransmit (e.g. Com_TriggerTransmit)
PDU路由器模块应提供不同模块在单独的头文件中使用的函数,例如:如果使用CanTp和FrIf,PDU路由器模块将提供PduR_CanIf。h,PduR_CanTp。h和PduR_FrIf.h。
2.2、I-PDU浅析
I-PDU由静态I-PDU ID标识,因为在编译PduR模块后必须标识I-PDU, PduR模块使用静态配置表中的I-PDU ID来确定I-PDU的目标。I-PDU用于PDUR上层模块的数据交换,如COM模块和DCM模块。路由器模块的路由操作并不修改I-PDU,它只是将I-PDU转发给目标模块。在TP路由时,IPDU的传递可以在收到完整I-PDU之前开始,即“动态网关”。而对于网络管理数据交换,可以绕过PduR模块实现。
I-PDU ID配置时,需要同时配置实现的API。如此,可以在每个接收I-PDU ID的模块中高效地实现查找表(例如,PduR模块的配置包含PduR_CanIfTxConfirmation的I-PDU ID)。
每个处理I-PDU并为I-PDU提供API的BSW模块必须包含I-PDU ID列表,这意味着每个被调用的模块将有标识I-PDU的查询表(注意标红这两段话,下图进行解释)。
COM模块调用PduR_ComTransmit (PDUR模块将列出I-PDU ID) , PDUR模块将调用CanIf_Transmit(CanIf模块配置将列出I-PDUID) , CanIf将调用PduR_CanIfTxConfirmation(PDUR模块配置将列出I-PDU ID)和PDUR模块将调用Com_TxConfirmation(COM模块配置将列出I-PDU ID)。
PduR模块通过源模块I-PDU ID(位于PDUR配置中)和目标模块I-PDU ID(位于被调用的目标模块配置中)的组合唯一地标识路由路径。PDUR模块应将I-PDU ID转换为传输路径和确认路径的目标模块。
比如,COM模块将I-PDU传输给CanIf和LinIf。调用PduR_comtransmission。 PduR模块将源IPDU ID(PDUR模块配置)转换为I-PDU ID (LinIf模块配置)和I-PDU ID(CanIf模块配置)。从COM模块接收到的PduInfoType值被复制到CanIf和LinIf模块,而不做任何更改。
名词缩写
缩写 | 描述 |
Up | Upper Layer Modules:上层模块,上文也有描述,一般是DCM、COM等,下文会出现 PduR_<User:Up>Transmit 等API,此处的Up可以平替为DCM\COM等 |
Lo | Lower Layer Modules:下层模块 一般是CanIf\CanTp等,下文出现PduR_<User:Lo>RxIndication等API,此处的Lo可以平替为CanIf\CanTp |
gatewaying-on | 网关功能;两个TP模块之间的路由,在接收到所有数据之前开始转发数据(当达到指定的阈值时)。如果在两个接口之间传输的数据量较大,则希望能够在接收到源网络的所有数据之前在目的网络上开始传输。这节省了内存和时间。 |
如果一个传输请求中有多个下层目的模块(1:n, n>1),则所有这些模块必须是CanIf模块或CanTp模块。不是它们的混合。
上述要求基本上是指COM模块不能请求传输,然后PDU Router模块使用同一个I-PDU将传输路由给CanTp模块和Canlf模块。
I-PDU在通信接口上有三种传输方式:
1、直接提供数据——当上层模块调用PduR_
2. 触发传输数据供应——其中下层通信接口模块通过使用I-PDU请求传输PduR_
3.当上层模块调用PduR_
I-PDU的发送确认对于直接发送和触发发送数据的规定是相同的:
如果I-PDU是上层模块发送的,则PDU Router模块不检查I-PDU的长度。
网关
PDU Router模块支持从一个源总线到一个或多个目的总线的I -PDU的网关。从本地模块发送和接收的不同之处在于,PDU Router模块必须同时是接收方和发送方,在某些情况下还为l-PDU提供缓冲。
I-PDU可以从一个源通信接口模块网关到一个(1:1)或多个目的通信接口模块(1:n I-PDU网关)。对于每个目的地,PDU路由器模块可以以可配置的深度缓冲一个I-PDU的每个目的地(如果有多个I-PDU,即FIFO)。一个I-PDU可能在上层模块发送到n个目的通信接口的同时被网关接收。
使用TP传输的i - pdu可以被网关到一个或多个目的地TP模块,其范围如下:
1、单帧和多帧都可以被网关到多个目标TP模块或本地模块(例如DCM)。
2、在多个n- pdu中传输的I-PDU可以“即时”被网关发送到一个目的地,这意味着在目的地TP模块上开始传输之前不需要收到完整的I-PDU
3、在多个n - pdu中传输的I-PDU可以被网关发送到另一个TP模块,也可以被本地模块接收,但不能同时发送到另一个TP模块。
4、使用TP模块传输的I-PDU不能被FIFO缓冲,即PDU路由器不能缓冲一个以上的I-PDU。
5、I- pdu只能在通信接口模块或TP模块之间网关,不能混合使用。例如,不能从canf接收到I-PDU,不能将其发送到LinTp。
这意味着PDU Router模块将从一个下层模块(源网络)接收到的I-PDU转发到由提供的I-PDU ID标识的下层模块(目的网络)。请注意,在本节中,“Src”和“Dst”用于可配置api。这只是为了明确哪个调用属于源模块和目标模块。
2.3、接口浅析
与上层模块交互的可配置接口定义
由于API描述现在采用了通用方法,因此上层API函数的服务id也是通用的。上层API函数的通用服务id由上层模块id和服务基id组成。
为与上层模块交互而定义的接口的通用服务id,应使用如下上层模块id
例如 服务函数PduR_ComTransmit的ID是0x89
较低层通信接口(If与Tp)模块交互的可配置接口定义
由于API描述现在采用了通用方法,所以底层通信接口API函数的服务id也是通用的。底层通信接口API函数通用服务id由底层接口模块id和服务基id组成。
3、时序图解析
3.1、CanIf模块I-PDU接收
CanIf调用PDUR层定义的API PduR_CanIfRxIndication 传递数据到PDUR,然后PDUR再调用Com_RxIndication将数据传递到COM,在COM将数据Copy一下,其实就是数据传递。
FrIf与LinIf是一样的时序图,不再过多描述。
3.2、CanTp模块I-PDU接收
TP牵涉到诊断服务,此处时序图列举为DCM,TP有单帧、多帧,下面时序图为了突出多帧传输的数据可以多次传递,最终一个接收确认即可。
3.3、CanIf模块I-PDU发送
其实与I-PDU的接收恰好是反着的,多了一个发送确认函数。按照下面1、2、3、4的顺序执行下去就行了,注意下面的注释 没有专用buffer可用的。
3.4、CanTp模块I-PDU发送
主要还是考虑多帧以及单帧,数据传递一次传输不完。
3.5、两个CanIf之间的网关
此处有个注意点,一定是两个CAN节点间的,例如CAN1到CAN2,CAN1接收数据,此时传到PDUR,PDUR反手调用CAN2的If层函数发出去,然后CAN2再向PDUR回复一个发送好了就完成了网关转发。
3.6、信号传到COM再网关出去
其实还是在PDUR转一下,只是把信号往上传传而已。
假设用的只是基本的功能,其实各家工具一般导入DBC文件中之后,默认生成的arxml配置已经足够使用了,一旦有自己定制,脚本处理arxml更快捷准确的。