角色与系统边界:上层模块、Interface 与传输协议之间的 I-PDU 转发
PDU Router(PduR)是经典通信栈的核心转发中枢。它从源模块接收 I-PDU,并将其原样且一致地传输到一个或多个目标模块 [SWS_PduR_00160] 。路由仅沿着配置的路由路径进行 [SWS_PduR_00162] 。一条路径由两项信息唯一确定:来自 PduR 配置的源 I-PDU-ID 和来自被调用目标模块配置的目标 I-PDU-ID [SWS_PduR_00161] 。因此,PduR 的核心功能是转换 I-PDU-ID。这同样适用于发送路径以及确认和指示路径 [SWS_PduR_00766] 。每个模块自行选择其句柄 ID;配置通过“全局”Pdu 将它们关联起来 ECU Configuration 图 3.13 第192页 。
PduR 上方是诸如 Com 和 DCM 等模块。下方是诸如 CanIf、FrIf 和 LinIf 等 Communication Interface 以及诸如 CanTp、FrTp 和 LinTp 等传输协议 SWS PDU Router 第24页 。接口采用通用定义。占位符 <Up>、<Lo> 和 <LoTp> 通过 PduRBswModules 中引用的模块配置进行替换,对于 CDD 则通过其 apiServicePrefix [SWS_PduR_00504] SWS PDU Router 图 10.2 第95页 进行替换。如果底层模块同时支持 TP 和 IF,则会添加中缀 Tp 和 If [SWS_PduR_00800] 。
kontext
cluster_oben
Obere Module (<Up>)
cluster_if
Communication Interfaces (<Lo>)
cluster_tp
Transportprotokolle (<LoTp>)
Com
Com
PduR
PduR
Routing-Tabellen, I-PDU-ID-Umsetzung,
Gateway-Puffer
Com->PduR
PduR_ComTransmit
Dcm
Dcm
Dcm->PduR
PduR_<User:Up>Transmit
BswM
BswM
BswM->PduR
PduR_EnableRouting,
PduR_DisableRouting
PduR->Com
Com_RxIndication,
Com_TxConfirmation,
Com_TriggerTransmit
PduR->Dcm
Dcm_StartOfReception, Dcm_CopyRxData,
Dcm_CopyTxData, Dcm_TpRxIndication,
Dcm_TpTxConfirmation
Det
Det
PduR->Det
开发与
运行时错误
CanIf
CanIf
PduR->CanIf
<Lo>_Transmit
FrIf
FrIf
PduR->FrIf
LinIf
LinIf
PduR->LinIf
CanTp
CanTp
PduR->CanTp
<LoTp>_Transmit
FrTp
FrTp
PduR->FrTp
LinTp
LinTp (in LinIf)
PduR->LinTp
CanIf->PduR
PduR_<User:Lo>RxIndication,
TxConfirmation, TriggerTransmit
CanTp->PduR
PduR_<User:LoTp>StartOfReception,
CopyRxData, CopyTxData,
RxIndication, TxConfirmation
上下文图:PduR 位于上层模块与底层 IF 或 TP 模块之间;BswM 切换路由路径组,错误报告给 DET。来源:[SWS_PduR_00504] 、[SWS_PduR_00615] 、[SWS_PduR_00119] 、SWS PDU Router 第16页
如果设置了 PduRZeroCostOperation 且所有路由路径均为 Pre-Compile,则相邻模块可以直接相互调用 [SWS_PduR_00287] 。如果至少有一条路径不是 Pre-Compile,生成器必须报告错误 [SWS_PduR_00619] SWS PDU Router 第56页 。生成器应优化掉未使用的特性,即 TP、IF、网关和 FIFO [SWS_PduR_00764] 。
生命周期:从 PDUR_UNINIT 经 PduR_Init 到 PDUR_ONLINE
PduR 恰好具有一个状态机 [SWS_PduR_00644] 。它具有来自 PduR_StateType [SWS_PduR_00324] [SWS_PduR_00742] 的状态 PDUR_UNINIT 和 PDUR_ONLINE。上电后,该模块处于 PDUR_UNINIT [SWS_PduR_00325] 。在成功执行 PduR_Init 后,它切换到 PDUR_ONLINE [SWS_PduR_00326] 。仅在 PDUR_ONLINE 中进行路由 [SWS_PduR_00328] ;在 PDUR_UNINIT 中不路由任何内容 [SWS_PduR_00330] SWS PDU Router 图 7.2 第53页 。较早的示意图还显示了初始化失败后的状态 PDUR_REDUCED SWS PDU Router (alt) 第30页 。对于 R20-11,该状态不适用,因为此处仅有两个状态。
zustaende
Powerup
Powerup
UNINIT
PDUR_UNINIT
无路由;
除 PduR_Init 和 PduR_GetVersionInfo 外的 API
报告 PDUR_E_UNINIT(在启用了 PduRDevErrorDetect 时)
Powerup->UNINIT
immediate
ONLINE
PDUR_ONLINE
根据路由表进行路由
UNINIT->ONLINE
PduR_Init(ConfigPtr) 无错误:
释放缓冲区,设置默认值,
根据配置激活路由路径组
ONLINE->ONLINE
erneuter PduR_Init:
PDUR_E_UNINIT an DET
状态图:上电后,PduR 处于 PDUR_UNINIT 状态且不进行路由;仅在无错误地执行 PduR_Init 后,它才在 PDUR_ONLINE 状态下进行路由。来源:[SWS_PduR_00325] 、[SWS_PduR_00326] 、[SWS_PduR_00119] 、[SWS_PduR_00100] 、SWS PDU Router 图 7.2 第53页
PduR_Init(ConfigPtr) 是同步且不可重入的 [SWS_PduR_00334] 。该函数完成三件事:
在初始化之前,如果 PduRDevErrorDetect 处于激活状态 [SWS_PduR_00119] ,则除 PduR_Init 和 PduR_GetVersionInfo 之外的所有函数都会报告错误 PDUR_E_UNINIT。PduR_GetVersionInfo [SWS_PduR_00338] 通过 PduRVersionInfoApi 启用 System Template 第656页 。
Post-Build 数据位于 PduR_PBConfigType 中并在 PduR_PBcfg.c 中实现 [SWS_PduR_00241] [SWS_PduR_00743] 。它们通过 PduRConfigurationId 唯一标识 [SWS_PduR_00281] 。该标识由 PduR_GetConfigurationId [SWS_PduR_00341] [SWS_PduR_00280] 作为基于 uint16 的 PduR_PBConfigIdType 提供;一个 ECU 可以包含多个可选配置 [SWS_PduR_00771] 。路由表可以在 Post-Build 时更新 [SWS_PduR_00295] ,但只能在未初始化状态下进行 [SWS_PduR_00296] 。内存需求可能会随着新配置而增加,因此必须在设计阶段予以规划 SWS PDU Router 第160页 。
Communication Interface 路径:Transmit、TriggerTransmit 与确认
当上层模块调用 PduR_<User:Up>Transmit 时 [SWS_PduR_00406] ,PduR 会针对每个目标调用 <Lo>_Transmit [SWS_PduR_00625] 。在此过程中,它不进行缓冲 [SWS_PduR_00629] 。对于返回值,适用以下规则:
多播的目标要么全部是 Interface,要么全部是传输协议,绝不混合 [SWS_PduR_00633] 。
CanIf 在 Transmit 时直接复制数据 SWS PDU Router 图 9.5 第100页 。相反,FrIf 和 LinIf 稍后通过 PduR_<User:Lo>TriggerTransmit 获取数据 [SWS_PduR_00369] 。PduR 将该调用转发至 <Up>_TriggerTransmit [SWS_PduR_00430] 并返回其返回值 [SWS_PduR_00661] SWS PDU Router 图 9.6 第101页 。PduR_<User:Lo>TxConfirmation [SWS_PduR_00365] 连同结果一起传递给 <Up>_TxConfirmation [SWS_PduR_00627] 。对于多播,这仅在最后一次确认后发生 [SWS_PduR_00589] 。
通过 Communication Interfaces 发送 I-PDU Com PduR CanIf FrIf PduR_ComTransmit(TxPduId, PduInfoPtr) Quell-I-PDU-ID in Ziel-I-PDU-ID umsetzen alt 具有直接数据提供功能的目标(CanIf) CanIf_Transmit(PduId, PduInfoPtr) copy data() Std_ReturnType 带有 TriggerTransmit 的目标(FrIf、LinIf) FrIf_Transmit(PduId, PduInfoPtr) set flag() Std_ReturnType 返回值(单播未更改) Use Case: 稍后:FlexRay 周期中的发送时刻 PduR_<User:Lo>TriggerTransmit(TxPduId, PduInfoPtr) Com_TriggerTransmit(TxPduId, PduInfoPtr) copy buffer() E_OK, SduLength 返回值未更改 Use Case: 传输后 PduR_<User:Lo>TxConfirmation(TxPduId, result) Com_TxConfirmation(TxPduId, result) 通过 CanIf 进行的确认流程相同; 多播时仅在最后一次确认后进行
时序图:来自 Com 的发送,具有直接数据提供(CanIf)或通过 TriggerTransmit 延迟数据获取(FrIf),各自随后带有确认。来源:[SWS_PduR_00625] 、[SWS_PduR_00430] 、[SWS_PduR_00627] 、SWS PDU Router 图 9.5 第100页 、SWS PDU Router 图 9.6 第101页
在接收时,PduR_<User:Lo>RxIndication [SWS_PduR_00362] 会导致对每个上层目标调用 <Up>_RxIndication [SWS_PduR_00621] ;支持 1:n [SWS_PduR_00164] SWS PDU Router 图 9.1 第97页 。PduR 既不在本地接收时检查长度 [SWS_PduR_00744] ,也不在本地发送时检查长度 [SWS_PduR_00745] 。
传输协议路径:DCM 与 TP 模块之间的分段 I-PDU
在进行 TP 发送时,PduR 会针对每个目标调用 <LoTp>_Transmit [SWS_PduR_00634] 。TP 模块通过 PduR_<User:LoTp>CopyTxData [SWS_PduR_00518] 分段获取数据。PduR 将每个请求转发至 <Up>_CopyTxData [SWS_PduR_00299] 并透传返回值 [SWS_PduR_00676] SWS PDU Router 图 9.9 第104页 。
在多播时,上层必须多次提供相同的数据。第一个目标的请求以 TP_CONFPENDING 发送至上层 [SWS_PduR_00631] ,所有后续请求则以 TP_DATARETRY 发送 [SWS_PduR_00632] 。在最后一次确认后,上层会收到唯一的一个 <Up>_TpTxConfirmation。如果至少有一个目标报告了 E_OK [SWS_PduR_00765] SWS PDU Router 图 9.10 第83页 ,则它会报告 E_OK。
来自 Dcm 的 TP 多播发送 Dcm PduR CanTp FrTp PduR_<User:Up>Transmit(TxPduId, PduInfoPtr) CanTp_Transmit(PduId, PduInfoPtr) Std_ReturnType FrTp_Transmit(PduId, PduInfoPtr) Std_ReturnType Std_ReturnType loop 对于传输的每个位置 PduR_<User:LoTp>CopyTxData(id, info, retry, availableDataPtr) Dcm_CopyTxData(…) TpDataState = TP_CONFPENDING BufReq_ReturnType BufReq_ReturnType PduR_<User:LoTp>CopyTxData(id, info, retry, availableDataPtr) Dcm_CopyTxData(…) TpDataState = TP_DATARETRY BufReq_ReturnType BufReq_ReturnType PduR_<User:LoTp>TxConfirmation(id, result) PduR_<User:LoTp>TxConfirmation(id, result) 在最后一次确认之后: 如果至少有一个目标报告 E_OK,则为 E_OK Dcm_TpTxConfirmation(id, result)
时序图:在来自 DCM 的 TP 多播中,PduR 为每个目标使用 TP_CONFPENDING 或 TP_DATARETRY 查询相同的数据,并汇总确认。来源:[SWS_PduR_00634] 、[SWS_PduR_00631] 、[SWS_PduR_00632] 、[SWS_PduR_00765] 、SWS PDU Router 图 9.10 第83页
TP 接收以 PduR_<User:LoTp>StartOfReception 开始 [SWS_PduR_00507] 。PduR 将其转发至 <Up>_StartOfReception [SWS_PduR_00549] 并原样返回其返回值 [SWS_PduR_00623] 。随后进行两次转发:
带有 SduLength 0 的调用用于查询可用缓冲区或可用数据 [SWS_PduR_00740] SWS PDU Router 图 9.4 第99页 。PduR 会将中止转发至每个目标。PduR_<User:Up>CancelTransmit 会导致 <Lo>_CancelTransmit 或 <LoTp>_CancelTransmit [SWS_PduR_00769] [SWS_PduR_00723] [SWS_PduR_00724] 。PduR_<User:Up>CancelReceive 会导致 <LoTp>_CancelReceive [SWS_PduR_00727] 。
TP-Empfang von CanTp an Dcm CanTp PduR Dcm PduR_<User:LoTp>StartOfReception(id, info, TpSduLength, bufferSizePtr) Dcm_StartOfReception(…) BUFREQ_OK, bufferSizePtr 返回值未更改 loop 对于每个后续段 PduR_<User:LoTp>CopyRxData(id, info, bufferSizePtr) Dcm_CopyRxData(…) copy data() BufReq_ReturnType BufReq_ReturnType PduR_<User:LoTp>RxIndication(id, result) Dcm_TpRxIndication(id, result)
时序图:在从 CanTp 到 DCM 的 TP 接收过程中,PduR 1:1 透传 StartOfReception、CopyRxData 循环以及 RxIndication。来源:[SWS_PduR_00549] 、[SWS_PduR_00428] 、[SWS_PduR_00429] 、SWS PDU Router 图 9.4 第99页
网关运行:直接转发、FIFO 缓冲区与实时 TP
在 Communication Interface 之间,PduR 进行 1:n 路由 [SWS_PduR_00436] 并采用直接转发,即没有自身的速率控制 [SWS_PduR_00437] 。网关仅在 IF↔IF 或 TP↔TP 之间进行 [SWS_PduR_00638] 。对于转发的长度,适用以下规则:
一个 I-PDU 可以同时在本地发送给 Com 并转发至第二个 CAN SWS PDU Router 图 9.14 第114页 。
目标如何获取数据由 PduRDestPduDataProvision 决定:
可为每个目标 I-PDU 配置一个 FIFO [SWS_PduR_00307] 。FIFO 行为自 PduRQueueDepth 大于 1 起适用 [SWS_PduR_00785] 。活动图汇总了输入和输出规则 [SWS_PduR_00665] [SWS_PduR_00666] 。
gateway_fifo
rx
缓冲网关路径上的
PduR_<SrcLo>RxIndication
prov
PduRDestPduDataProvision?
rx->prov
dleer
FIFO 为空且没有
TxConfirmation 处于挂起状态?
prov->dleer
PDUR_DIRECT
tleer
FIFO leer?
prov->tleer
PDUR_TRIGGERTRANSMIT
ddirekt
<DstLo>_Transmit direkt aufrufen;
FIFO bleibt leer
dleer->ddirekt
是
voll
FIFO voll?
dleer->voll
不
tkopie
I-PDU in FIFO kopieren,
<DstLo>_Transmit aufrufen
tleer->tkopie
是
tleer->voll
不
flush
清空 FIFO,
向 DET 报告 PDUR_E_PDU_INSTANCES_LOST;
新 I-PDU 按 FIFO 为空处理
voll->flush
是
einreihen
将 I-PDU 作为最新条目排入队列
voll->einreihen
不
tt
PduR_<DstLo>TriggerTransmit
ttleer
FIFO leer?
tt->ttleer
ttnok
返回 E_NOT_OK
ttleer->ttnok
是
ttok
复制并移除最旧条目;
FIFO 非空:使用最旧 I-PDU
调用 <DstLo>_Transmit
ttleer->ttok
不
conf
PduR_<DstLo>TxConfirmation
(direkte Datenbereitstellung)
confnext
FIFO 非空:使用最旧 I-PDU
调用 <DstLo>_Transmit,之后将其移除
conf->confnext
活动图:根据数据提供方式和 FIFO 填充水平,网关转发的 I-PDU 会立即发送、排队或在溢出后重新开始;TriggerTransmit 和 TxConfirmation 会清空 FIFO。来源:[SWS_PduR_00665] 、[SWS_PduR_00793] 、[SWS_PduR_00786] 、[SWS_PduR_00787] 、[SWS_PduR_00255] 、[SWS_PduR_00669] 、[SWS_PduR_00666] 、[SWS_PduR_00667] 、[SWS_PduR_00662]
TP 网关有两种方法。在直接网关(Direct Gatewaying)中,<DstLoTp>_Transmit 在带有 E_OK 的 RxIndication 中启动 [SWS_PduR_00551] 。在实时网关(On-the-fly-Gatewaying)中,一旦达到 PduRTpThreshold,就会立即启动继续发送 [SWS_PduR_00317] 。此时仅允许一个目标 [SWS_PduR_00708] ,并且已发送的数据不会重发 [SWS_PduR_00707] SWS PDU Router 第58页 。PduR 根据大小选择缓冲区:
伴随 TxConfirmation,它释放缓冲区 [SWS_PduR_00637] 。如果 I-PDU 还应在本地接收,PduR 会按此顺序调用 <UpTp>_StartOfReception、<UpTp>_CopyRxData 和 <UpTp>_RxIndication [SWS_PduR_00789] 。为此它必须进行缓冲,因为 DCM 对网关不知情 SWS PDU Router 第112页 。
TP-I-PDU 从 CAN1 到 CAN2 的 On-the-fly 网关 CanTp (CAN1, Quelle) PduR CanTp (CAN2, Ziel) PduR_<User:LoTp>StartOfReception(id, info, TpSduLength, bufferSizePtr) 选择缓冲区:当 TpSduLength ≤ PduRPduMaxLength 时使用专用缓冲区, 否则从 PduRTxBuffer 动态分配 BUFREQ_OK(无缓冲区:BUFREQ_E_OVFL) loop bis PduRTpThreshold erreicht PduR_<User:LoTp>CopyRxData(id, info, bufferSizePtr) copy data() BUFREQ_OK CanTp_Transmit(PduId, PduInfoPtr) Std_ReturnType loop 剩余段,交错 PduR_<User:LoTp>CopyRxData(…) BUFREQ_OK PduR_<User:LoTp>CopyTxData(id, info, retry, availableDataPtr) BUFREQ_OK PduR_<User:LoTp>RxIndication(id, result) PduR_<User:LoTp>TxConfirmation(id, result) 为此目标释放缓冲区 仅允许一个目标 TP 模块; 不对已发送数据进行重复传输
时序图:在两个 CAN 网络之间的实时网关中,达到阈值时便已开始继续发送;接收和发送交错进行。来源:[SWS_PduR_00317] 、[SWS_PduR_00708] 、[SWS_PduR_00797] 、[SWS_PduR_00799] 、[SWS_PduR_00637] 、SWS PDU Router 图 9.15 第110页
路由路径组:在运行时切换路由
路由路径组按网络或 PDU 类型捆绑路径。它们通常由 BswM 进行切换 SWS PDU Router 第69页 。为此使用 PduR_EnableRouting(id) [SWS_PduR_00615] 和 PduR_DisableRouting(id, initialize) [SWS_PduR_00617] ;标识符为类型 uint16 [SWS_PduR_00654] 。激活立即生效 [SWS_PduR_00715] 。禁用时适用以下规则:
后续版本明确列出了受影响的函数 SWS PDU Router 第69页 。
routinggruppen
aufruf
PduR_EnableRouting(id) 或
PduR_DisableRouting(id, initialize)
exist
Routing-Pfadgruppe id
existiert?
aufruf->exist
det
PduRDevErrorDetect aktiv?
exist->det
不
art
Aufruf?
exist->art
是
meld
PDUR_E_ROUTING_PATH_GROUP_ID_INVALID
melden
det->meld
是
keine
无动作返回
det->keine
不
meld->keine
ein
立即激活组:
后续的 Transmit 将被直接处理
art->ein
EnableRouting
aus
Gruppe deaktivieren
art->aus
DisableRouting
fifo
带 FIFO 的路径 (PduRQueueDepth > 1):
清空 FIFO,PDUR_E_PDU_INSTANCES_LOST
aus->fifo
init
initialize = TRUE:单缓冲区设为默认值
initialize = FALSE:保留当前值
fifo->init
gesperrt
带有已禁用路径的 I-PDU-ID 的 API:
E_NOT_OK 且无进一步动作
init->gesperrt
活动图:如果组 ID 未知,调用将直接返回而不执行任何操作(视情况附带 DET 报告);否则立即激活或禁用该组,并执行 FIFO 清空和缓冲区处理。来源:[SWS_PduR_00647] 、[SWS_PduR_00648] 、[SWS_PduR_00716] 、[SWS_PduR_00649] 、[SWS_PduR_00715] 、[SWS_PduR_00663] 、[SWS_PduR_00717]
Mode Management Guide 推荐针对不具有 Com-I-PDU 组的 I-PDU(例如 LdCom)使用路径组。通过 BswM 规则进行切换,例如取决于 Partial Network 状态 Mode Management Guide 第50页 。为此,BswM 动作 BswMPduRouterControl 调用 PduR_EnableRouting 或 PduR_DisableRouting SWS BSW Mode Manager 第145页 。在到本地模块的 n:1 路由中,运行时最多只能有一条路径处于活动状态 System Template 第736页 [SWS_PduR_00615] 。
发生错误时的行为
开发错误由 [SWS_PduR_00100] 定义。仅在 PduRDevErrorDetect 处于激活状态时才会报告它们 [SWS_PduR_00119] [SWS_PduR_00221] 。PduR 不报告生产错误 SWS PDU Router 第60页 。
错误代码 值 触发条件
PDUR_E_INIT_FAILED0x00 无效的配置指针
PDUR_E_UNINIT0x01 初始化之前的 API 或 PDUR_UNINIT 之外的 PduR_Init
PDUR_E_PDU_ID_INVALID0x02 无效的 PDU 标识符
PDUR_E_ROUTING_PATH_GROUP_ID_INVALID0x08 Enable/Disable 时未知的组 [SWS_PduR_00648] [SWS_PduR_00649]
PDUR_E_PARAM_POINTER0x09 空指针作为参数
运行时错误 PDUR_E_PDU_INSTANCES_LOST 在三种情况下发生:
PduR 使用 Det_ReportRuntimeError 作为其强制接口 [SWS_PduR_91001] 。
在 IF 路径上,PduR 本身不处理错误。它将返回值透传给源 [SWS_PduR_00626] SWS PDU Router 第46页 ,且不重传 [SWS_PduR_00256] 。在 TP 路径上,错误同样通过返回值传递给上层 [SWS_PduR_00700] SWS PDU Router 第49页 。当存在多个目标时,仅当所有目标都返回 E_OK 时 E_OK 才成立 [SWS_PduR_00701] 。该规则可能指 TP 多播,而对于 IF 多播适用 [SWS_PduR_00218] 。PduR 仅转发错误的 TP-RxIndication [SWS_PduR_00207] 。 问题 Q-4bd42fd8dc77ccf2 (未决)
对于 TP 网关适用专门的规则:
进一步详细证据
以下出处支撑了本指南的论述。规范第 9 章中的时序对它们进行了说明,例如 SWS PDU Router 图 9.5 第100页 。
基于 SWS PDU Router(R20-11)的 Requirements 及关联文档位置由 AI 生成的指南;仅所链接的 Requirements 具有规范约束力。标记为解释的论述请根据规范进行核对。
gemini-3.8-flash-low· 2026-10-13 · 德文原文