模块 comstack 定义了 Classic 通信栈的通用类型集。其中包括 PduIdType、PduLengthType、PduInfoType、BufReq_ReturnType、RetryInfoType 以及通道与子网标识符,全部通过 ComStack_Types.h 提供([SWS_COMTYPE_00011] 、[SWS_COMTYPE_00038] )。总线接口、传输协议、PduR、诊断模块和 RTE 使用相同的类型;RTE 显式导入这些类型(SWS RTE 第833页 )。
kontext
types
ComStack_Types.h
PduIdType, PduLengthType, PduInfoType,
BufReq_ReturnType, RetryInfoType,
NetworkHandleType, PNCHandleType
cfg
EcuC-Konfiguration
→ ComStack_Cfg.h
cfg->types
erzeugt Breite von
PduIdType, PduLengthType
rte
RTE
rte->types
importiert
com
Com / LdCom
pdur
PduR
com->pdur
Transmit / RxIndication
(PduIdType, PduInfoType*)
dcm
Dcm
dcm->pdur
TP-API
(BufReq_ReturnType, RetryInfoType)
secoc
SecOC
secoc->pdur
TP 和 IF-API
tp
CanTp / FrTp / J1939Tp
pdur->tp
Transmit / CopyTxData /
CopyRxData
ifs
CanIf / LinIf / FrIf
pdur->ifs
Transmit / TxConfirmation
comm
ComM / Nm
comm->types
NetworkHandleType,
PNCHandleType
上下文图:适用于所有层的统一类型集,通过 EcuC 配置确定大小。来源:[SWS_COMTYPE_00005] 、SWS RTE 第833页
句柄和长度取决于配置。PduIdType 为 uint8 或 uint16,PduLengthType 为 uint8、uint16 或 uint32;两者均根据 EcuC 配置生成([SWS_COMTYPE_00005] 、[SWS_COMTYPE_00008] )。每个提供模块自行选择其句柄 ID。它们只需在各自 API 内保持唯一;PduR 会沿路由路径转换它们(ECU Configuration 第156页 )。
PduInfoType 整合了有效载荷指针、元数据指针和长度。该结构借此承载发送请求、接收指示与 Trigger Transmit。大 PDU 被分块复制:传输协议通过 PduR 重复调用上限层的 CopyTxData(SWS PduR 第109页 )。接收从 StartOfReception 开始,并通过 CopyRxData 继续。
通过 PduR 进行 Dcm → CanTp 的 TP 发送 Dcm PduR CanTp PduR_<User:Up>Transmit(PduIdType, const PduInfoType*) CanTp_Transmit(PduIdType, const PduInfoType*) E_OK E_OK loop 直至所有数据发送完毕 PduR_CanTpCopyTxData(id, info, retry, availableDataPtr) Dcm_CopyTxData(id, info, retry, availableDataPtr) 将数据复制到 info->SduDataPtr BUFREQ_OK, *availableDataPtr BUFREQ_OK, *availableDataPtr PduR_CanTpTxConfirmation(PduIdType, Std_ReturnType) Dcm_TpTxConfirmation(PduIdType, Std_ReturnType)
时序图:传输协议在循环中从 DCM 提取发送数据;确认在最后进行。来源:SWS PduR 第109页
错误与瓶颈由 BufReq_ReturnType 上报([SWS_COMTYPE_00012] ):
BUFREQ_E_BUSY:暂时无缓冲区或数据不足;允许重试调用。
BUFREQ_E_OVFL:无所需长度的缓冲区。
BUFREQ_E_NOT_OK:中止。
TP 发送时的确认与重传由 RetryInfoType 通过 TP_DATACONF、TP_CONFPENDING、TP_DATARETRY 以及偏移量 TxTpDataCnt 来控制([SWS_COMTYPE_00027] 、[SWS_COMTYPE_00037] )。
其他标识符类型扩充了该类型集。NetworkHandleType(uint8)标识一个通信通道。TPParameterType 选择 STmin、Block Size 或带宽控制以进行更改([SWS_COMTYPE_00031] )。PNCHandleType 在 R20-11 中派生自 uint8([SWS_COMTYPE_00036] );R23-11 版本不同,指明为 uint16(SWS ComStackTypes 第17页 )。
更多 ›
角色:通信栈的通用类型集
模块 comstack 不提供任何自有服务。它定义了 Classic 通信栈各模块相互通信时所使用的数据类型。其中包括 PduIdType、PduLengthType、PduInfoType、BufReq_ReturnType、TpDataStateType、RetryInfoType、TPParameterType、NetworkHandleType 和 PNCHandleType。它们可通过 ComStack_Types.h 获取([SWS_COMTYPE_00011] 、[SWS_COMTYPE_00037] 、[SWS_COMTYPE_00038] )。解释:因此该模块本身不具有运行时行为。 问题 Q-766338989232e06a (未决) 流程、状态与错误响应仅在各接口中使用这些类型的模块中产生。
因此,系统边界贯穿整个通信栈。使用相同类型的包括:
kontext
types
ComStack_Types.h
PduIdType, PduLengthType, PduInfoType,
BufReq_ReturnType, RetryInfoType,
NetworkHandleType, PNCHandleType
cfg
EcuC-Konfiguration
→ ComStack_Cfg.h
cfg->types
erzeugt Breite von
PduIdType, PduLengthType
rte
RTE
rte->types
importiert
com
Com / LdCom
pdur
PduR
com->pdur
Transmit / RxIndication
(PduIdType, PduInfoType*)
dcm
Dcm
dcm->pdur
TP-API
(BufReq_ReturnType, RetryInfoType)
secoc
SecOC
secoc->pdur
TP 和 IF-API
tp
CanTp / FrTp / J1939Tp
pdur->tp
Transmit / CopyTxData /
CopyRxData
ifs
CanIf / LinIf / FrIf
pdur->ifs
Transmit / TxConfirmation
comm
ComM / Nm
comm->types
NetworkHandleType,
PNCHandleType
上下文图:从总线接口到 RTE 的所有层均依赖于来自 ComStack_Types.h 的相同类型集;其大小根据 EcuC 配置生成。来源:[SWS_COMTYPE_00005] 、SWS RTE 第833页 、SWS PduR 第33页 、SWS ComM 第171页
PDU 句柄与长度:PDU 的标识与大小
PduIdType 是范围在 0…<PduIdmax> 内的从零开始的整数。其位宽(uint8 或 uint16)取决于单个软件模块所管理的最大 PDU 数量。生成器工具根据虚拟 EcuC 层中在 ComStack_Cfg.h 内配置的值生成它([SWS_COMTYPE_00005] )。对应的参数 PduIdTypeEnum 规定了规则:只要没有模块处理超过 256 个 PDU,UINT8 即已足够,否则需要 UINT16(ECU Configuration 第153页 )。
类似地,PduLengthType 依赖于配置,表现为 uint8、uint16 或 uint32。决定性因素是 ECU 发送的 PDU 的最大长度([SWS_COMTYPE_00008] )。传输协议也从 EcuC 派生长度:CanTp 根据 EcuC 参数 PduLength 确定 N-PDU 的最大发送长度(SWS CanTp 第60页 )。
通信栈的 API 将两件事结合在一起:指向 PDU 数据缓冲区的指针,以及确定该指针属于哪个 PDU 的句柄 ID。句柄 ID 的值由提供模块自由选择。因此,同一 PDU 可以以 ID 5 从 Com 发送至 PduR,并以 ID 19 从 PduR 发送至 CanIf。该 ID 只需在相应 API 的作用域内保持唯一(ECU Configuration 第156页 )。为了使两个模块能够引用同一个 PDU,在虚拟模块配置 EcuC 中存在与模块无关的 EcucPduCollection(ECU Configuration 第154页 )。PduR 通过源 ID 和目标 ID 识别路由路径,转换这些 ID,并不加修改地传递 PduInfoType 值(SWS PduR 第33页 )。
handle
ecuc
EcucPduCollection (EcuC)
gemeinsame Pdu-Objekte
com
Com
ecuc->com
对 PDU 的引用
pdur
PduR
Routing-Pfad = Quell-ID + Ziel-IDs
ecuc->pdur
对 PDU 的引用
canif
CanIf
ecuc->canif
对 PDU 的引用
linif
LinIf
ecuc->linif
对 PDU 的引用
com->pdur
PduR_ComTransmit(ID = 5, PduInfoType*)
pdur->canif
ID = 19
PduInfoType 保持不变
pdur->linif
自有 LinIf-ID
PduInfoType 保持不变
协作图:每个接口拥有各自的句柄 ID;PduR 对其进行转换,而公共 PDU 则通过 EcucPduCollection 引用。来源:ECU Configuration 第156页 、ECU Configuration 第154页 、SWS PduR 第33页
PduInfoType:集有效载荷、元数据和长度于一体的结构
PduInfoType 整合了三个元素([SWS_COMTYPE_00011] ):
SduDataPtr 指向有效载荷。
MetaDataPtr 指向 CAN-ID、套接字 ID 或诊断地址等元数据。它们的长度和类型按 PDU 进行静态配置;超过 8 位的元素按平台字节序排列。
类型为 PduLengthType 的 SduLength 指定 SDU 长度(以字节为单位)。
同一结构支持多种交互形式:
发送请求: <Mod>_Transmit(TxPduId, const PduInfoType*) 传递长度、数据指针与元数据指针,并返回 E_OK 或 E_NOT_OK(SWS CanIf 第87页 )。
接收指示: <Mod>_RxIndication(RxPduId, const PduInfoType*)。在 CanNm 中,数据指针仅在指示返回前有效(SWS CanNm 第73页 )。
Trigger Transmit: PduInfoPtr 既作输入也作输出。调用时,SduLength 包含可用缓冲区大小;返回时包含已复制数据的长度(SWS CanIf 第107页 )。在先前的发送请求中,上限层仅传递长度;此时 SduDataPtr 指向 NULL(SWS CanIf 第158页 )。
TP 复制接口: StartOfReception、CopyRxData 和 CopyTxData,返回值为 BufReq_ReturnType(SWS PduR 第93页 )。
传输协议缓冲区:分段复制而非整块传递
大 PDU 不会作为整体传递。发送方分块提取数据:DCM 通过 PduR 触发 CanTp_Transmit。随后 CanTp 重复调用 PduR_CanTpCopyTxData,该调用被转发至 Dcm_CopyTxData。末尾为 PduR_CanTpTxConfirmation 和 Dcm_TpTxConfirmation(SWS PduR 第109页 )。对于 CopyTxData 的参数:
info 提供目标缓冲区与待复制字节数。
值为 0 的 SduLength 仅上报 retry 参数中的状态变化或查询可用数据量;此时 SduDataPtr 可以为 NULL_PTR(SWS PduR 第93页 )。
availableDataPtr 上报剩余发送数据量。具有动态有效载荷长度的 TP 模块(如 FrIsoTp)以此确定后续的连续帧(SWS LdCom 第34页 )。
通过 PduR 进行 Dcm → CanTp 的 TP 发送 Dcm PduR CanTp PduR_<User:Up>Transmit(PduIdType, const PduInfoType*) CanTp_Transmit(PduIdType, const PduInfoType*) E_OK E_OK loop 直至所有数据发送完毕 PduR_CanTpCopyTxData(id, info, retry, availableDataPtr) Dcm_CopyTxData(id, info, retry, availableDataPtr) 将数据复制到 info->SduDataPtr BUFREQ_OK, *availableDataPtr BUFREQ_OK, *availableDataPtr PduR_CanTpTxConfirmation(PduIdType, Std_ReturnType) Dcm_TpTxConfirmation(PduIdType, Std_ReturnType)
时序图:在 TP 发送时,传输协议在循环中通过 PduR 从上限层拉取数据;确认仅在最后一个段之后发出。来源:SWS PduR 第109页 、SWS PduR 第93页 、[SWS_COMTYPE_00012]
接收分三步进行:
StartOfReception 建立连接。info 承载首帧或单帧的数据及元数据,若两者均不存在则为 NULL_PTR。TpSduLength 指明总长度。接收方通过 bufferSizePtr 上报其空闲缓冲区;传输协议据此计算 Block Size(SWS PduR 第92页 )。
每次 CopyRxData 调用提供 I-PDU 的下一个分块并写回剩余缓冲区大小(SWS PduR 第91页 )。
RxIndication 结束接收。
若 TP-PDU 还需要被网关转发,PduR 会自行缓冲该 PDU,因为 DCM 对网关转发一无所知(SWS PduR 第112页 )。
通过 PduR 进行 CanTp → Dcm 的 TP 接收 CanTp PduR Dcm PduR_CanTpStartOfReception(id, info, TpSduLength, bufferSizePtr) Dcm_StartOfReception(id, info, TpSduLength, bufferSizePtr) BUFREQ_OK, *bufferSizePtr BUFREQ_OK, *bufferSizePtr bufferSizePtr 用于 计算块大小 (BS) loop je empfangenem Segment (N-PDU) PduR_CanTpCopyRxData(id, info, bufferSizePtr) Dcm_CopyRxData(id, info, bufferSizePtr) BUFREQ_OK, *bufferSizePtr (Restpuffer) BUFREQ_OK, *bufferSizePtr (Restpuffer) PduR_CanTpRxIndication(PduIdType, Std_ReturnType) Dcm_TpRxIndication(PduIdType, Std_ReturnType)
时序图:TP 接收以缓冲区协商开始,以分段方式继续,并以指示结束。来源:SWS PduR 第112页 、SWS PduR 第92页 、SWS PduR 第91页
确认与重传:RetryInfoType 与 TpDataStateType
RetryInfoType 包含两个字段([SWS_COMTYPE_00037] ):
TpDataState 描述 TP 缓冲区的状态。
TxTpDataCnt 指定自当前位置起的偏移量,用以确定重新发送的字节数。
TpDataStateType 包含三个值([SWS_COMTYPE_00027] ):
TP_DATACONF:迄今复制的所有数据均已确认,并允许从 TP 缓冲区中移除。本次调用中复制的数据除外。
TP_DATARETRY:重新复制已复制的数据以纠正错误。TxTpDataCnt 指定起始偏移量。
TP_CONFPENDING:迄今复制的数据必须保留在 TP 缓冲区中以便进行错误恢复。
若 retry 本身即为 NULL_PTR,则允许在复制后立即释放数据(SWS PduR 第93页 )。
copytx
start
CopyTxData(id, info, retry, availableDataPtr)
r
retry == NULL_PTR?
start->r
frei
复制后数据
可立即移除
r->frei
是
st
TpDataState?
r->st
不
len
info->SduLength == 0?
frei->len
conf
TP_DATACONF:
已确认目前复制的数据,
可从 TP 缓冲区移除
st->conf
pend
TP_CONFPENDING:
目前复制的数据
保留在 TP 缓冲区中
st->pend
retr
TP_DATARETRY:
ab Offset TxTpDataCnt
erneut kopieren
st->retr
conf->len
pend->len
retr->len
abfrage
仅状态切换或
查询可用数据;
SduDataPtr 允许为 NULL_PTR
len->abfrage
是
genug
genug Sendedaten vorhanden?
len->genug
不
busy
nichts kopieren,
BUFREQ_E_BUSY;
unterer Layer darf wiederholen
genug->busy
不
ok
Daten kopieren,
BUFREQ_OK,
*availableDataPtr setzen
genug->ok
是
活动图:CopyTxData 调用首先评估 retry 参数,然后决定执行复制还是返回 BUFREQ_E_BUSY。来源:SWS PduR 第93页 、[SWS_COMTYPE_00027] 、[SWS_COMTYPE_00012]
J1939 传输协议图示具体展示了这一交互:
每个块使用 TP_DATACONF 请求第一个数据包,后续数据包使用 TP_CONFPENDING 请求。
若一个 TP.DT 丢失,传输将重新从该块的第一个数据包开始。为此设置 TP_DATARETRY,且 TxTpDataCnt 包含到块开头的偏移量(SWS J1939Tp 第55页 )。
并非所有使用者都会评估该参数:根据规范,对于 LdCom,retry 既不被 LdCom 处理,也不被其上限层处理(SWS LdCom 第34页 )。
J1939 传输协议中的重试处理 PduR (Sender) J1939Tp (Sender) J1939Tp(接收方) J1939Tp_Transmit(PduIdType, const PduInfoType*) TP.CM_RTS TP.CM_CTS loop je Block loop je Paket PduR_J1939TpCopyTxData(id, info, retry, availableDataPtr) TpDataState = TP_DATACONF(块的第一个报文) 或 TP_CONFPENDING(后续报文) TP.DT opt TP.DT verloren 下一个报文 = 块的第一个报文 PduR_J1939TpCopyTxData(retry) TpDataState = TP_DATARETRY TxTpDataCnt = 相对于块起始位置的偏移量 TP.EOMACK PduR_J1939TpTxConfirmation(...)
时序图:带确认状态的分块传输,以及在数据包丢失时跳回块开头。来源:SWS J1939Tp 第55页 、[SWS_COMTYPE_00027] 、[SWS_COMTYPE_00037]
通道、子网与 TP 参数
NetworkHandleType 为 uint8,取值范围为从零开始的 0..255。它存储通信通道的标识符([SWS_COMTYPE_00038] )。后续版本的示例:
PNCHandleType 存储 Partial Network Cluster 的标识符,在 R20-11 中派生自 uint8([SWS_COMTYPE_00036] )。而 R23-11 的文档出处则指明为 uint16(SWS ComStackTypes 第17页 )。对于 R20-11,以需求为准。PNC 标识符的使用上下文例如 ComM 中的同步 PNC 关闭(SWS ComM 第171页 )。
TPParameterType 指定要修改其值的传输协议参数([SWS_COMTYPE_00031] ):
TP_STMIN:Separation Time,
TP_BS:Block Size,
TP_BC:FlexRay 传输协议的带宽控制。
Block Size 和 STmin 例如出现在 FlexRay-AR 传输协议的流控帧中(SWS FrArTp 第47页 )。
发生错误时的行为
缓冲区请求的结果由 BufReq_ReturnType 描述([SWS_COMTYPE_00012] ):
BUFREQ_OK (0):成功。
BUFREQ_E_NOT_OK (1):缓冲区无法访问。
BUFREQ_E_BUSY (2):暂时无可用缓冲区;请求者应在一定时间后重试。
BUFREQ_E_OVFL (3):无法提供所需长度的缓冲区。
各接口按如下方式对应这些值:
CopyTxData: 若发送数据不足,则不复制任何内容并返回 BUFREQ_E_BUSY;下限层可以重试调用(SWS PduR 第93页 )。在 DCM 的分页缓冲区流程中,BUFREQ_E_BUSY 与准备下一页交替出现(SWS DCM 第481页 )。
StartOfReception: BUFREQ_E_NOT_OK 拒绝连接并中止接收;bufferSizePtr 保持不变。BUFREQ_E_OVFL 因无所需长度的缓冲区而中止。在返回 BUFREQ_OK 且无请求大小的缓冲区时,上报缓冲区大小 0(SWS DCM 第273页 )。
CopyRxData: BUFREQ_E_NOT_OK 表示由于错误未复制任何内容(SWS PduR 第91页 )。
TP 中的传输错误: 通过 TP_DATARETRY 配合偏移量 TxTpDataCnt 进行恢复([SWS_COMTYPE_00027] )。
TriggerTransmit: E_NOT_OK 表示未复制任何内容。此时不得使用 PduInfoPtr,因为它可能为 NULL 或无效(SWS CanIf 第107页 )。
其他检查由使用模块自行定义。示例:
进一步详细证据
以下概述对最重要的出处进行了归类([SWS_COMTYPE_00005] 至 [SWS_COMTYPE_00038] ):
基于负载中提供的需求与文档出处 AI 生成的指南;引用的文档出处部分来自后续版本(R23-11 至 R25-11)。对 R20-11 具有规范效力的是需求 SWS_COMTYPE_*。
gemini-3.8-flash-low· 2026-10-13 · 德文原文