# AUTOSAR SWS TimeSyncOverCAN — CAN 时间同步规范 ## 文档元信息 | 字段 | 值 | |------|-----| | **文档标题** | Specification of Time Synchronization over CAN(基于 CAN 的时间同步规范) | | **文档所有者** | AUTOSAR | | **文档责任方** | AUTOSAR | | **文档标识号** | 674 | | **文档状态** | Final(最终版) | | **所属 AUTOSAR 标准** | Classic Platform(经典平台) | | **所属标准版本** | 4.4.0 | ## 文档变更历史 | 日期 | 版本 | 变更人 | 变更说明 | |------|------|--------|----------| | 2018-10-31 | 4.4.0 | AUTOSAR Release Management | • 修改以增强全局时间同步的精度
• 其他次要更正/澄清/编辑修改;详情请参阅 ChangeDocumentation | | 2017-12-08 | 4.3.1 | AUTOSAR Release Management | • 次要更正/澄清/编辑修改 | | 2016-11-30 | 4.3.0 | AUTOSAR Release Management | • 偏移消息格式变更
• 新增扩展偏移消息格式
• 立即时间同步消息传输
• 各种增强和更正 | | 2015-07-31 | 4.2.2 | AUTOSAR Release Management | • `CanTSyn_SetTransmissionMode` 改为返回 `void`
• 次要更正/澄清/编辑修改 | | 2014-10-31 | 4.2.1 | AUTOSAR Release Management | • 初始发布 | ## 目录 - [1 介绍与功能概述](#1-介绍与功能概述) - [2 缩写、缩略语和定义](#2-缩写缩略语和定义) - [3 相关文档](#3-相关文档) - [3.1 输入文档](#31-输入文档) - [3.2 相关规范](#32-相关规范) - [4 约束和假设](#4-约束和假设) - [4.1 限制](#41-限制) - [4.2 适用域](#42-适用域) - [5 与其他模块的依赖](#5-与其他模块的依赖) - [5.1 文件结构](#51-文件结构) - [6 需求追踪](#6-需求追踪) - [7 功能规范](#7-功能规范) - [7.1 概述](#71-概述) - [7.2 模块处理](#72-模块处理) - [7.3 消息格式](#73-消息格式) - [7.4 作为时间主站](#74-作为时间主站) - [7.5 作为时间从站](#75-作为时间从站) - [7.6 错误分类](#76-错误分类) - [8 API 规范](#8-api-规范) - [9 时序图](#9-时序图) - [10 配置规范](#10-配置规范) --- ## 1 介绍与功能概述 CanTSyn 模块处理 CAN 总线上时间信息的分发。 仅通过广播 CAN 消息将时间信息从主站传输到从站的方式存在一个缺点:即由于仲裁和 BSW 特定延迟等 CAN 特定效应,时间值变得不准确。 该概念提出了一种两步机制: - 在第一个广播消息(即所谓的 **SYNC 消息**)中,传输时间信息的第二部分(`t0r`)。发送 ECU,即时间主站,使用 CAN 低级机制(如"CAN 发送确认")来检测消息实际发送的时间点(`t1r`),即获取时间戳。接收 ECU,即时间从站,接收消息并使用 CAN 低级机制(如"CAN 接收指示")来检测消息实际接收的时间点(`t2r`)。 - 在第二个广播消息(即所谓的 **Follow-Up (FUP) 消息**)中,时间主站传输先前在 SYNC 消息中传输的时间信息与实际检测到的发送时间之间的偏移。FUP 消息不获取时间戳,无论是在发送方还是接收方。 - 时间从站现在可以组合 SYNC 和 FUP 消息中的信息,以及其先前对接收到的 SYNC 消息所获取的时间戳,并通过仅接收一条消息并省略时间戳的方式,以更精确的方式确定传输的时间信息。 **图 1:CAN 时间同步机制**(参见原文 PDF 第 5 页) --- ## 2 缩写、缩略语和定义 本节列出模块本地缩写和定义。有关同步时基相关的完整缩写和定义集,请参阅 [4] 中的相应章节。 | 缩写/缩略语 | 描述 | |------------|------| | (G)TD | (Global) Time Domain((全局)时间域) | | (G)TM | (Global) Time Master((全局)时间主站) | | `TSyn` | 总线特定的时间同步模块 | | CAN | Controller Area Network(控制器局域网) | | CanTSyn | CAN 时间同步模块 | | CRC | Cyclic Redundancy Checksum(循环冗余校验) | | Debounce Time | 具有相同 PDU 的两个 Tx 消息之间的最小间隔 | | DEM | Diagnostic Event Manager(诊断事件管理器) | | DET | Default Error Tracer(默认错误追踪器) | | DLC | Data Length Code(数据长度代码) | | FUP message | Follow-Up message(后续消息) | | OFNS message | Offset adjustment message(偏移调整消息) | | OFS message | Offset Synchronization message(偏移同步消息) | | StbM | Synchronized Time-Base Manager(同步时基管理器) | | SYNC message | Time Synchronization message(时间同步消息) | | TG | Time Gateway(时间网关) | | Timesync | Time Synchronization(时间同步) | | TS | Time Slave(时间从站) | | TSD | Time Sub-domain(时间子域) | --- ## 3 相关文档 ### 3.1 输入文档 | 编号 | 文档 | |------|------| | [1] | Requirements on Synchronized Time-Base Manager — AUTOSAR_SRS_SynchronizedTimeBaseManager.pdf | | [2] | Layered Software Architecture — AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf | | [3] | General Specification of Basic Software Modules — AUTOSAR_SWS_BSWGeneral.pdf | | [4] | Specification of Synchronized Time-Base Manager — AUTOSAR_SWS_SynchronizedTimeBaseManager.pdf | | [5] | Specification of CRC Routines — AUTOSAR_SWS_CRCLibrary.pdf | | [6] | Specification of CAN Interface — AUTOSAR_SWS_CANInterface.pdf | | [7] | Specification of Default Error Tracer — AUTOSAR_SWS_DefaultErrorTracer.pdf | | [8] | Specification of Basic Software Mode Manager — AUTOSAR_SWS_BSWModeManager.pdf | ### 3.2 相关规范 AUTOSAR 提供了关于基础软件的一般规范(SWS BSW General [3]),该规范对 CanTSyn 也有效。 因此,关于基础软件的一般规范(SWS BSW General)应被视为 CanTSyn 的附加规范和所需规范。 --- ## 4 约束和假设 ### 4.1 限制 当前版本的 CanTSyn 不支持硬件时间戳功能。第一个后果是由于 Rx-/Tx-ISR 延迟和获取虚拟本地时间之前的执行时间,时间同步精度较低。 第二个后果是需要在 CAN 驱动程序中不对全局时间 PDU 嵌套中断(即,强烈建议不要以轮询模式调用 TX 确认和 RX 指示函数)。 SYNC 和 OFS 消息中的时基限制为 32 位,因此支持的最大时间值为 4294967295 秒(2^32-1)。 时间主站、时间网关和时间从站应使用最坏情况精度为 2µs 的时基参考时钟工作。 ### 4.2 适用域 需要公共时基的系统,无论 ECU 连接到哪种总线系统。 --- ## 5 与其他模块的依赖 CAN 时间同步(CanTSyn)具有到同步时基管理器(StbM)、CAN 接口(CanIf)、基础软件模式管理器(BswM)和默认错误追踪器(DET)的接口。 **图 2:CanTSyn 模块的模块依赖关系**(参见原文 PDF 第 9 页) 主要依赖关系: - **StbM** — 获取和设置当前时间值 - `StbM_GetCurrentVirtualLocalTime`(强制) - `StbM_BusGetCurrentTime`(可选) - `StbM_GetTimeBaseStatus`(可选) - `StbM_BusSetGlobalTime`(可选) - `StbM_GetOffset`(可选) - `StbM_GetTimeBaseUpdateCounter`(可选) - `StbM_GetCurrentTime`(可选) - **CanIf** — 接收和发送消息 - `CanIf_Transmit`(可选) - **BswM** — 通过 `CanTSyn_SetTransmissionMode()` 协调网络访问 - **DET** — 报告开发错误 - `Det_ReportError`(可选) - **CRC** — `Crc_CalculateCRC8H2F`(可选) ### 5.1 文件结构 #### 5.1.1 代码文件结构 有关详细信息,请参阅 SWS BSW General [3] 的第 5.1.6 节"代码文件结构"。 #### 5.1.2 头文件结构 有关详细信息,请参阅 SWS BSW General [3] 的第 5.1.7 节"头文件结构"。 --- ## 6 需求追踪 | 需求 | 描述 | 由以下需求实现 | |------|------|----------------| | RS_TS_00003 | 时间同步实现应在启动时将本地时基初始化为零 | SWS_CanTSyn_00003, SWS_CanTSyn_00006 | | RS_TS_00004 | 时间同步实现应将全局时基初始化为可配置的启动值 | SWS_CanTSyn_00003, SWS_CanTSyn_00006 | | RS_TS_20031 | CAN 时间同步模块应触发时基同步传输 | SWS_CanTSyn_00025, 00026, 00028, 00032, 00035, 00036, 00038, 00043, 00044, 00117, 00118, 00119, 00120, 00121, 00122, 00123, 00124, 00125, 00136 | | RS_TS_20032 | CAN 时间同步模块应在接收到有效 Timesync/TS 消息后提供时基 | SWS_CanTSyn_00064, 00072, 00133, 00135 | | RS_TS_20033 | CAN 时间同步模块应支持保护时间同步协议的方法 | SWS_CanTSyn_00007, 00015, 00016, 00017, 00018, 00031, 00041, 00048, 00049, 00050, 00054, 00055, 00056, 00111, 00112, 00126, 00127, 00128, 00129 | | RS_TS_20034 | CAN 时间同步模块应检测并处理时间同步协议中的超时和完整性错误 | 多个 SWS_CanTSyn 需求 | | RS_TS_20035 | CAN 时间同步模块应支持精确时间测量和 CAN 上同步的协议 | 多个 SWS_CanTSyn 需求 | | RS_TS_20036 | CAN 时间同步模块应使用时间测量和同步协议来发送和接收偏移值 | 多个 SWS_CanTSyn 需求 | | RS_TS_20037 | CAN 时间同步模块应支持时间测量和同步协议中的用户特定数据 | SWS_CanTSyn_00011, 00012, 00013, 00014 | | RS_TS_20038 | CAN 时间同步模块配置应允许时间同步实现支持时基的不同角色 | SWS_CanTSyn_00108, 00135 | | RS_TS_20068 | CAN 时间同步模块应支持经典 CAN 和 CAN FD | SWS_CanTSyn_00010, 00015, 00016, 00017, 00018, 00036, 00041, 00055, 00071, 00072, 00077, 00085, 00111, 00112, 00130, 00131, 00132 | | SRS_BSW_00323 | 所有 AUTOSAR BSW 模块应检查传入的 API 参数的有效性 | SWS_CanTSyn_00088, 00097, 00100, 00134 | | SRS_BSW_00337 | 开发错误分类 | SWS_CanTSyn_00097, 00100, 00134 | | SRS_BSW_00385 | 列出可能的错误通知 | SWS_CanTSyn_00089 | --- ## 7 功能规范 本章定义了 CAN 时间同步的行为。模块的 API 在第 8 章中定义,配置在第 10 章中定义。 ### 7.1 概述 CAN 时间同步负责实现 CAN 特定的时间同步协议。时间同步原理和通用术语在 [4] 中描述。 ### 7.2 模块处理 本节包含 CAN 时间同步的辅助功能描述。 **`[SWS_CanTSyn_00135]⌈`** 如果 CanTSyn 调用 StbM 的 API,则应使用通过相应时间域的 `CanTSynSynchronizedTimeBaseRef` 参数引用的时基的时基 ID。`⌋(RS_TS_20032, RS_TS_20038)` #### 7.2.1 中断处理 在发送或接收 SYNC 消息时,需要在 Rx 指示 / Tx 确认回调中捕获虚拟本地时间的当前值: - 在中断模式下,在 Rx/Tx 中断上下文中捕获 - 或在主函数的轮询模式下捕获(注意:强烈建议不要对 GTS 使用轮询模式) 中断本身发生和确定当前虚拟本地时间之间的任何延迟都会降低发送或接收时基的精度。 因此,这些 Rx 指示 / Tx 确认回调在调用后立即建立中断保护是不可避免的(如果在禁用中断嵌套的 Rx/Tx 中断上下文中调用,则控制器隐式确保这一点)。 之后仅进行必要的检查以确定消息是 SYNC 消息(并在必要时确定时基 ID)。一旦确认时基 ID 和 SYNC 消息类型,通过调用 StbM 的函数获取虚拟本地时间的当前值(仍在锁定中断的上下文中)。此后,可以删除中断保护而不会对精度产生负面影响。 因此,可能会出现一种情况:尽管后续的帧检查(例如 CRC 验证、SC 验证)可能失败并导致快照变得多余,但仍然会获取虚拟本地时间的快照。 #### 7.2.2 初始化 通过 `CanTSyn_Init()` 初始化 CAN 时间同步。除了 `CanTSyn_GetVersionInfo()` 和 `CanTSyn_Init()` 之外,时间同步的 API 函数只能在模块已正确初始化后调用。 **`[SWS_CanTSyn_00003]⌈`** 对 `CanTSyn_Init()` 的调用初始化所有内部变量并将 CAN 时间同步设置为已初始化状态。`⌋(RS_TS_00003, RS_TS_00004)` **`[SWS_CanTSyn_00006]⌈`** 在已初始化状态下调用 `CanTSyn_Init()` 时,CAN 时间同步应重新初始化其内部变量。`⌋(RS_TS_00003, RS_TS_00004)` **`[SWS_CanTSyn_00007]⌈`** 序列计数器(SC)应初始化为 0。`⌋(RS_TS_20033)` ### 7.3 消息格式 SYNC、FUP、OFS 和 OFNS 消息分配给专用的消息类型"TimeSync"。 同一时间域的 SYNC、FUP、OFS 和 OFNS 消息通过使用多路复用信号组共享相同的 CAN ID。对于不同的时间域,如果 Timesync 消息由同一时间主站或时间网关发送,则可以使用相同的 CAN ID。如果 Timesync 消息由不同的时间主站或时间网关发送,则应使用不同的 CAN ID。多路复用器位于字节 0,称为"Type"。 CRC 的使用是可选的。为确保多个时间观察单元之间的高度可变性,配置决定如果接收方不支持 CRC 计算,则如何处理 CRC 保护的 Timesync 消息。因此,接收方可能仅使用给定的时基值而不评估 CRC。 **`[SWS_CanTSyn_00008]⌈`** 时间同步消息中时间值信号的字节顺序为"Big Endian"(大端)。`⌋(RS_TS_20035)` **`[SWS_CanTSyn_00010]⌈`** 对于经典 CAN,SYNC、FUP、OFS 和 OFNS 消息的 DLC 为 8。如果 `CanTSynUseExtendedMsgFormat` 为 TRUE,则对于 CAN FD,SYNC、FUP、OFS 和 OFNS 消息的 DLC 为 16。`⌋(RS_TS_20035, RS_TS_20068)` **`[SWS_CanTSyn_00011]⌈`** 根据其类型,时间同步消息可以包含给定消息格式中的用户数据。`⌋(RS_TS_20035, RS_TS_20037)` **`[SWS_CanTSyn_00012]⌈`** 应从包含用户数据字段的传入时间同步消息中一致地读取用户数据。`⌋(RS_TS_20037)` **`[SWS_CanTSyn_00013]⌈`** 应将用户数据一致地写入包含用户数据字段的传出时间同步消息。`⌋(RS_TS_20037)` **`[SWS_CanTSyn_00014]⌈`** 用户数据应映射到 `StbM_UserDataType`,其中消息中给定的字节号和 `StbM_UserDataType` 中的字节号应匹配(用户字节 0 映射到 `StbM_UserDataType.userByte0` 等)。之后应相应地设置 `StbM_UserDataType.userDataLength`。`⌋(RS_TS_20037)` #### 7.3.1 SYNC 和 FUP 消息 **`[SWS_CanTSyn_00015]⌈`** SYNC 非 CRC 保护的消息格式: ``` 字节 0: Type = 0x10 字节 1: 用户字节 1, 默认: 0 字节 2: D = 时间域 0 到 15(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 用户字节 0, 默认: 0 字节 4-7: SyncTimeSec = 48 位时间秒部分的 32 位 LSB 如果 CanTSynUseExtendedMsgFormat = TRUE: 字节 8-15: 保留, 始终为 0 ``` `⌋(RS_TS_20033, RS_TS_20035, RS_TS_20068)` **`[SWS_CanTSyn_00016]⌈`** FUP 非 CRC 保护的消息格式: ``` 字节 0: Type = 0x18 字节 1: 用户字节 2, 默认: 0 字节 2: D = 时间域 0 到 15(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 保留(位 7 到位 3), 默认: 0 SGW(位 2) SyncToGTM = 0 SyncToSubDomain = 1 OVS = 秒的溢出(位 1 到位 0) 字节 4-7: SyncTimeNSec = 32 位时间值(纳秒) 如果 CanTSynUseExtendedMsgFormat = TRUE: 字节 8-15: 保留, 始终为 0 ``` `⌋(RS_TS_20033, RS_TS_20035, RS_TS_20068)` **`[SWS_CanTSyn_00017]⌈`** SYNC CRC 保护的消息格式: ``` 字节 0: Type = 0x20 字节 1: CRC 字节 2: D = 时间域 0 到 15(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 用户字节 0, 默认: 0 字节 4-7: SyncTimeSec = 48 位时间秒部分的 32 位 LSB 如果 CanTSynUseExtendedMsgFormat = TRUE: 字节 8-15: 保留, 始终为 0 ``` `⌋(RS_TS_20033, RS_TS_20035, RS_TS_20068)` **`[SWS_CanTSyn_00018]⌈`** FUP CRC 保护的消息格式: ``` 字节 0: Type = 0x28 字节 1: CRC 字节 2: D = 时间域 0 到 15(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 保留(位 7 到位 3), 默认: 0 SGW(位 2) SyncToGTM = 0 SyncToSubDomain = 1 OVS = 秒的溢出(位 1 到位 0) 字节 4-7: SyncTimeNSec = 32 位时间值(纳秒) 如果 CanTSynUseExtendedMsgFormat = TRUE: 字节 8-15: 保留, 始终为 0 ``` `⌋(RS_TS_20033, RS_TS_20035, RS_TS_20068)` #### 7.3.2 偏移消息 偏移消息可与时间同步消息多路复用(使用相同的 PDU 等)。 对于经典 CAN(CAN 2.0),使用两种不同的偏移消息 OFS 和 OFNS。对于这两者,都有带和不带 CRC 字段的变体。 对于 CAN FD,如果 `CanTSynUseExtendedMsgFormat` 为 TRUE,则 OFS 和 OFNS 的内容合并到单个扩展 OFS 消息中(也存在带和不带 CRC 字段的变体)。 **`[SWS_CanTSyn_00132]⌈`** 对于 CAN 2.0 总线,`CanTSynUseExtendedMsgFormat` 应始终为 FALSE。`⌋(RS_TS_20068)` **`[SWS_CanTSyn_00130]⌈`** 如果 `CanTSynUseExtendedMsgFormat` 为 FALSE,则应使用第 7.3.2.1 节中规定的正常偏移消息格式。`⌋(RS_TS_20068)` **`[SWS_CanTSyn_00131]⌈`** 如果 `CanTSynUseExtendedMsgFormat` 为 TRUE,则应使用第 7.3.2.2 节中规定的扩展偏移消息格式。`⌋(RS_TS_20068)` ##### 7.3.2.1 正常偏移消息 **`[SWS_CanTSyn_00126]⌈`** OFS 非 CRC 保护的消息格式: ``` 字节 0: Type = 0x34 字节 1: 用户字节 1, 默认: 0 字节 2: D = 时间域 16 到 31(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 用户字节 0, 默认: 0 字节 4-7: OfsTimeSec = 32 位偏移时间值(秒) ``` `⌋(RS_TS_20033, RS_TS_20036)` **`[SWS_CanTSyn_00127]⌈`** OFNS 非 CRC 保护的消息格式: ``` 字节 0: Type = 0x3C 字节 1: 用户字节 2, 默认: 0 字节 2: D = 时间域 16 到 31(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 保留(位 7 到位 1), 默认: 0 SGW(位 0) SyncToGTM = 0 SyncToSubDomain = 1 字节 4-7: OfsTimeNSec = 32 位偏移时间值(纳秒) ``` `⌋(RS_TS_20033, RS_TS_20036)` **`[SWS_CanTSyn_00128]⌈`** OFS CRC 保护的消息格式: ``` 字节 0: Type = 0x44 字节 1: CRC 字节 2: D = 时间域 16 到 31(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 用户字节 0, 默认: 0 字节 4-7: OfsTimeSec = 32 位偏移时间值(秒) ``` `⌋(RS_TS_20033, RS_TS_20036)` **`[SWS_CanTSyn_00129]⌈`** OFNS CRC 保护的消息格式: ``` 字节 0: Type = 0x4C 字节 1: CRC 字节 2: D = 时间域 16 到 31(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 保留(位 7 到位 1), 默认: 0 SGW(位 0) SyncToGTM = 0 SyncToSubDomain = 1 字节 4-7: OfsTimeNSec = 32 位偏移时间值(纳秒) ``` `⌋(RS_TS_20033, RS_TS_20036)` ##### 7.3.2.2 扩展偏移消息 如果 `CanTSynUseExtendedMsgFormat` 为 TRUE,则扩展 OFS 消息的消息布局如下。不需要单独的 OFNS 消息。 **`[SWS_CanTSyn_00111]⌈`** CAN FD PDU 的 OFS 非 CRC 保护的消息格式: ``` 字节 0: Type = 0x54 字节 1: 用户字节 2, 默认: 0 字节 2: D = 时间域 16 到 31(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 保留(位 7 到位 1), 默认: 0 SGW(位 0) SyncToGTM = 0 SyncToSubDomain = 1 字节 4: 用户字节 0, 默认: 0 字节 5: 用户字节 1, 默认: 0 字节 6: 保留, 默认: 0 字节 7: 保留, 默认: 0 字节 8-11: OfsTimeSec = 32 位偏移时间值(秒) 字节 12-15: OfsTimeNSec = 32 位偏移时间值(纳秒) ``` `⌋(RS_TS_20033, RS_TS_20036, RS_TS_20068)` **`[SWS_CanTSyn_00112]⌈`** CAN FD PDU 的 OFS CRC 保护的消息格式: ``` 字节 0: Type = 0x64 字节 1: CRC 字节 2: D = 时间域 16 到 31(位 7 到位 4) SC = 序列计数器(位 3 到位 0) 字节 3: 保留(位 7 到位 1), 默认: 0 SGW(位 0) SyncToGTM = 0 SyncToSubDomain = 1 字节 4: 用户字节 0, 默认: 0 字节 5: 用户字节 1, 默认: 0 字节 6: 保留, 默认: 0 字节 7: 保留, 默认: 0 字节 8-11: OfsTimeSec = 32 位偏移时间值(秒) 字节 12-15: OfsTimeNSec = 32 位偏移时间值(纳秒) ``` `⌋(RS_TS_20033, RS_TS_20036, RS_TS_20068)` ### 7.4 作为时间主站 时间主站是某个时基的主站,并将该时基传播到通信网络某个段内的一组时间从站,作为该时基的源。 如果时间主站也是全局时基(即从中导出所有其他时基的时基)的所有者,则它是全局时间主站。时间网关通常由一个时间主站端口组成,该端口连接到一个或多个时间从站。将时间实体映射到真实 ECU 时,必须注意,一个 ECU 对于一个时基可以是时间主站(甚至全局时间主站),对于另一个时基可以是时间从站。 **图 3:术语示例**(参见原文 PDF 第 21 页) **`[SWS_CanTSyn_00136]⌈`** 主站应通过使用从相应时间域的 `CanTSynGlobalTimePduRef` 派生的 PduId 调用 `CanIf_Transmit` 来发送 SYNC、FUP、OFS 和 OFNS 消息。`⌋(RS_TS_20031)` #### 7.4.1 SYNC 和 FUP 消息处理 **`[SWS_CanTSyn_00025]⌈`** 时间主站应以 SYNC 消息开始每个同步时基的时间同步序列。`⌋(RS_TS_20031, RS_TS_20035)` **`[SWS_CanTSyn_00026]⌈`** 时间主站应以 FUP 消息结束每个同步时基的时间同步序列。`⌋(RS_TS_20031, RS_TS_20035)` **`[SWS_CanTSyn_00027]⌈`** 等待 `CanTSyn_TxConfirmation()` 函数时的任何超时都会将状态机重置为开始新的 SYNC 传输。`⌋(RS_TS_20034, RS_TS_20035)` **`[SWS_CanTSyn_00028]⌈`** 对于同步时基,时间主站使用 SYNC 消息的循环传输(根据 9.1),周期为 `CanTSynGlobalTimeTxPeriod`(ECUC_CanTSyn_00017),前提是 `timeBaseStatus` 中的 `GLOBAL_TIME_BASE` 位已设置且 `CanTSynGlobalTimeTxPeriod` 不等于 0,并且关联的 `cyclicMsgResumeCounter` 未在运行(见 7.4.5)。`⌋(RS_TS_20031, RS_TS_20035)` #### 7.4.2 OFS 消息处理 **`[SWS_CanTSyn_00032]⌈`** 如果主站配置了 `CanTSynGlobalTimeTxCrcSecured`(`ECUC_CanTSyn_00186`)和/或支持用户数据,则主站应同时发送 CRC 保护的消息和/或带用户数据的偏移消息。`⌋(RS_TS_20031)` #### 7.4.3 传输模式 **`[SWS_CanTSyn_00035]⌈`** 当 `CanTSyn_SetTransmissionMode()`(`ECUC_CanTSyn_00018`)被调用并传递 `CANTSYN_TX_OFF` 时,CanTSyn 模块应停止触发任何 CanTSyn 消息。`⌋(RS_TS_20031, RS_TS_20036)` **`[SWS_CanTSyn_00036]⌈`** 当 `CanTSyn_SetTransmissionMode()`(`ECUC_CanTSyn_00018`)被调用并传递 `CANTSYN_TX_ON` 时,CanTSyn 模块应恢复或开始时间同步消息的触发。`⌋(RS_TS_20031, RS_TS_20036, RS_TS_20068)` **`[SWS_CanTSyn_00037]⌈`** `CanTSyn_SetTransmissionMode` 应是 `void` 类型,不返回任何值。`⌋(RS_TS_20034, RS_TS_20036)` #### 7.4.4 去抖时间 **`[SWS_CanTSyn_00038]⌈`** 如果 `CanTSynGlobalTimeTxDebounceTime`(`ECUC_CanTSyn_00086`)被配置为非零值,则主站不应在小于 `CanTSynGlobalTimeTxDebounceTime` 的间隔内发送两个连续消息。`⌋(RS_TS_20031, RS_TS_20036)` #### 7.4.5 立即时间同步 **`[SWS_CanTSyn_00039]⌈`** 在接收到来自 StbM 的全局时间值更新后,CanTSyn 模块应立即触发时间同步消息传输。`⌋(RS_TS_20036)` **`[SWS_CanTSyn_00040]⌈`** 立即传输触发后,主站应至少等待 `CanTSynGlobalTimeTxPeriod` 时间才能再次发送。`⌋(RS_TS_20036)` **`[SWS_CanTSyn_00041]⌈`** 立即传输机制可被去抖时间约束。`⌋(RS_TS_20033, RS_TS_20036, RS_TS_20068)` **`[SWS_CanTSyn_00042]⌈`** 在 `CanTSynGlobalTimeTxDebounceTime` 间隔内多次触发立即时间同步应导致 `cyclicMsgResumeCounter` 启动。`⌋(RS_TS_20034, RS_TS_20036)` #### 7.4.6 时间同步消息的计算和组装 **`[SWS_CanTSyn_00043]⌈`** 主站应使用通过 `StbM_GetCurrentTime` 从 StbM 获取的当前全局时间来组装时间同步消息。`⌋(RS_TS_20031, RS_TS_20035, RS_TS_20036)` **`[SWS_CanTSyn_00044]⌈`** 序列计数器在每次成功发送 SYNC 消息时递增。`⌋(RS_TS_20031, RS_TS_20035, RS_TS_20036)` ### 7.5 作为时间从站 时间从站是接收时间主站分发的时基的实体。 #### 7.5.1 SYNC 和 FUP 消息处理 **`[SWS_CanTSyn_00064]⌈`** 当从站接收到 SYNC 消息时,它应使用 CAN 接收指示机制获取本地时间戳。`⌋(RS_TS_20032, RS_TS_20034)` **`[SWS_CanTSyn_00065]⌈`** 从站应将 SYNC 消息中的序列计数器与最后接收到的有效序列计数器进行比较以检测丢失的消息。`⌋(RS_TS_20036)` **`[SWS_CanTSyn_00066]⌈`** 当从站接收到 FUP 消息时,它应使用 SYNC 消息中获取的时间戳和 FUP 消息中的偏移来计算全局时间。`⌋(RS_TS_20036)` #### 7.5.2 OFS 和 OFNS 消息处理 **`[SWS_CanTSyn_00072]⌈`** 从站应使用 OFS 和 OFNS 消息来调整本地时间到全局时间。`⌋(RS_TS_20032, RS_TS_20034, RS_TS_20068)` #### 7.5.3 时间同步消息的验证和分解 **`[SWS_CanTSyn_00073]⌈`** 从站应验证接收到的 SYNC、FUP、OFS 和 OFNS 消息的 CRC(如果配置了 CRC 保护)。`⌋(RS_TS_20035)` **`[SWS_CanTSyn_00074]⌈`** 从站应验证消息格式、DLC 和时间域。`⌋(RS_TS_20036)` **`[SWS_CanTSyn_00075]⌈`** 如果验证失败,从站应丢弃该消息并递增错误计数器。`⌋(RS_TS_20035)` **`[SWS_CanTSyn_00076]⌈`** 如果在配置的超时时间内未接收到 FUP 消息,从站应丢弃相关的 SYNC 消息。`⌋(RS_TS_20034, RS_TS_20035)` **`[SWS_CanTSyn_00077]⌈`** 从站应使用接收到的偏移来调整 StbM 中的全局时间。`⌋(RS_TS_20034, RS_TS_20035, RS_TS_20036, RS_TS_20068)` ### 7.6 错误分类 #### 7.6.1 开发错误 | 错误代码 | 描述 | |---------|------| | `CANTSYN_E_INIT_FAILED` | CanTSyn_Init 调用失败 | | `CANTSYN_E_PARAM` | 传递给 CanTSyn API 的参数无效 | | `CANTSYN_E_UNINIT` | API 服务在未初始化状态下被请求 | #### 7.6.2 运行时错误 | 错误代码 | 描述 | |---------|------| | `CANTSYN_E_MSG_TIMEOUT` | 消息超时 | | `CANTSYN_E_MSG_LOST` | 消息丢失 | #### 7.6.3 瞬态故障 未定义。 #### 7.6.4 生产错误 未定义。 #### 7.6.5 扩展生产错误 未定义。 --- ## 8 API 规范 ### 8.1 API #### 8.1.1 导入类型 `CanTSyn` 模块使用以下导入类型(来自其他 BSW 模块): - `Std_ReturnType`(来自 `Std_Types.h`) - `StbM_SynchronizedTimeBaseType`、`StbM_TimeStampType`、`StbM_UserDataType`(来自 `StbM`) - `Can_TimeStampType`(来自 `Can_GeneralTypes.h`) - `PduInfoType`、`PduIdType`(来自 `PduR`) - `Dem_EventStatusType`(来自 `Dem`) #### 8.1.2 类型定义 ```c /* CanTSyn 传输模式 */ typedef enum { CANTSYN_TX_OFF = 0, CANTSYN_TX_ON = 1 } CanTSyn_TransmissionModeType; /* CanTSyn 全局时间状态 */ typedef enum { CANTSYN_GLOBAL_TIME_BASE_NOT_SET = 0, CANTSYN_GLOBAL_TIME_BASE_SET = 1 } CanTSyn_GlobalTimeBaseStatusType; /* CanTSyn 时间域 ID */ typedef uint8 CanTSyn_TimeDomainIdType; ``` #### 8.1.3 函数定义 ##### `CanTSyn_Init` ```c void CanTSyn_Init( const CanTSyn_ConfigType* ConfigPtr ); ``` 初始化 CanTSyn 模块。 ##### `CanTSyn_GetVersionInfo` ```c void CanTSyn_GetVersionInfo( Std_VersionInfoType* VersionInfo ); ``` 返回 CanTSyn 模块的版本信息。 ##### `CanTSyn_SetTransmissionMode` ```c void CanTSyn_SetTransmissionMode( CanTSyn_TimeDomainIdType TimeDomainId, CanTSyn_TransmissionModeType TransmissionMode ); ``` 设置时间主站/时间网关的传输模式。 ##### `CanTSyn_MainFunction` ```c void CanTSyn_MainFunction( void ); ``` 由调度程序周期性调用的主函数。 #### 8.1.4 回调通知 ##### `CanTSyn_RxIndication` ```c void CanTSyn_RxIndication( PduIdType RxPduId, const PduInfoType* PduInfoPtr ); ``` 从 CanIf 模块接收到消息的回调指示。 ##### `CanTSyn_TxConfirmation` ```c void CanTSyn_TxConfirmation( PduIdType TxPduId ); ``` 来自 CanIf 模块的消息发送确认回调。 #### 8.1.5 计划函数 ##### `CanTSyn_MainFunction` 请参见上文 8.1.3。 #### 8.1.6 预期接口 | API | 描述 | |-----|------| | `StbM_GetCurrentVirtualLocalTime` | 获取当前虚拟本地时间 | | `StbM_BusGetCurrentTime` | 获取总线的当前时间 | | `StbM_GetTimeBaseStatus` | 获取时基状态 | | `StbM_BusSetGlobalTime` | 设置总线的全局时间 | | `StbM_GetOffset` | 获取时基偏移 | | `StbM_GetTimeBaseUpdateCounter` | 获取时基更新计数器 | | `StbM_GetCurrentTime` | 获取当前时间 | | `CanIf_Transmit` | 通过 CAN 接口发送消息 | | `Crc_CalculateCRC8H2F` | 计算 CRC8H2F | | `Det_ReportError` | 报告开发错误 | | `BswM_CanTSyn_TransmissionModeChange` | 通知 BswM 传输模式变更(可选) | --- ## 9 时序图 ### 9.1 CAN 时间同步(时间主站) 主站时序: 1. 主站通过 `StbM_GetCurrentTime()` 获取当前全局时间 2. 主站组装 SYNC 消息 3. 主站通过 `CanIf_Transmit()` 发送 SYNC 消息 4. 主站在 `CanTSyn_TxConfirmation()` 中获取发送时间戳 5. 主站组装 FUP 消息(包含 SYNC 时间与发送时间戳的偏移) 6. 主站通过 `CanIf_Transmit()` 发送 FUP 消息 **图 4:时间主站时序**(参见原文 PDF 第 46 页) ### 9.2 CAN 时间同步(时间从站) 从站时序: 1. 从站通过 `CanIf_RxIndication()` 接收到 SYNC 消息 2. 从站在 Rx 指示回调中获取接收时间戳 3. 从站等待 FUP 消息 4. 从站通过 `CanIf_RxIndication()` 接收到 FUP 消息 5. 从站使用 SYNC 时间戳和 FUP 偏移计算全局时间 6. 从站通过 `StbM_BusSetGlobalTime()` 将全局时间提供给 StbM **图 5:时间从站时序**(参见原文 PDF 第 47 页) --- ## 10 配置规范 ### 10.1 如何阅读本章 本章使用以下符号: - `<` 和 `>` 之间的内容是配置参数的占位符 - `[ ... ]` 表示可选元素 - 详细说明使用表格 ### 10.2 容器和配置参数 #### 10.2.1 变体 `CanTSyn` 模块支持以下配置变体: - `CanTSynGlobalTimeMaster`(时间主站变体) - `CanTSynGlobalTimeSlave`(时间从站变体) #### 10.2.2 `CanTSyn`(模块) | 配置项 | 类型 | 描述 | |--------|------|------| | `CanTSynGeneral` | 容器 | 通用配置参数 | | `CanTSynGlobalTimeDomain` | 容器(多) | 全局时间域配置 | | `CanTSynGlobalTimeMaster` | 容器 | 时间主站配置(条件性) | | `CanTSynGlobalTimeSlave` | 容器 | 时间从站配置(条件性) | #### 10.2.3 `CanTSynGeneral` | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynDevErrorDetect` | Boolean | 启用/禁用开发错误检测 | | `CanTSynVersionInfoApi` | Boolean | 启用 `CanTSyn_GetVersionInfo` API | | `CanTSynMainFunctionPeriod` | Float | 主函数周期 | | `CanTSynUseExtendedMsgFormat` | Boolean | 启用 CAN FD 扩展消息格式 | #### 10.2.4 `CanTSynGlobalTimeDomain` | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynSynchronizedTimeBaseRef` | Reference | 引用的同步时基 | | `CanTSynGlobalTimeTxPeriod` | Float | 时间同步消息的传输周期(秒),0 = 不传输 | | `CanTSynGlobalTimeTxDebounceTime` | Float | 两次传输之间的去抖时间(秒) | | `CanTSynGlobalTimeFollowUpTimeout` | Float | 等待 FUP 消息的超时时间(秒) | | `CanTSynGlobalTimeCrcSupport` | Boolean | 支持 CRC 保护的时间同步消息 | #### 10.2.5 `CanTSynGlobalTimeSyncDataIDList` 包含 SYNC 消息的 DataID 列表。 #### 10.2.6 `CanTSynGlobalTimeSyncDataIDListElement` | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimeSyncDataIDValue` | Integer | SYNC DataID 值 | | `CanTSynGlobalTimeSyncDataIDLength` | Integer | DataID 长度(位) | #### 10.2.7 `CanTSynGlobalTimeFupDataIDList` 包含 FUP 消息的 DataID 列表。 #### 10.2.8 `CanTSynGlobalTimeFupDataIDListElement` | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimeFupDataIDValue` | Integer | FUP DataID 值 | | `CanTSynGlobalTimeFupDataIDLength` | Integer | DataID 长度(位) | #### 10.2.9 `CanTSynGlobalTimeOfsDataIDList` 包含 OFS 消息的 DataID 列表。 #### 10.2.10 `CanTSynGlobalTimeOfsDataIDListElement` | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimeOfsDataIDValue` | Integer | OFS DataID 值 | | `CanTSynGlobalTimeOfsDataIDLength` | Integer | DataID 长度(位) | #### 10.2.11 `CanTSynGlobalTimeOfnsDataIDList` 包含 OFNS 消息的 DataID 列表。 #### 10.2.12 `CanTSynGlobalTimeOfnsDataIDListElement` | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimeOfnsDataIDValue` | Integer | OFNS DataID 值 | | `CanTSynGlobalTimeOfnsDataIDLength` | Integer | DataID 长度(位) | #### 10.2.13 `CanTSynGlobalTimeMaster` 时间主站的配置。 | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimeMasterId` | Integer | 时间主站 ID | | `CanTSynGlobalTimeTxCrcSecured` | Boolean | 主站是否发送 CRC 保护的消息 | | `CanTSynGlobalTimeTxCrcValidated` | Boolean | 主站是否验证 CRC | | `CanTSynImmediateTimeSync` | Boolean | 启用立即时间同步 | | `CanTSynCyclicMsgResumeCounter` | Integer | 立即同步的循环消息恢复计数器(消息数) | #### 10.2.14 `CanTSynGlobalTimeMasterPdu` 时间主站使用的 PDU 配置。 | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimePduRef` | Reference | 全局时间 PDU 引用 | | `CanTSynPduDirection` | Enum | PDU 方向(发送/接收) | | `CanTSynPduCanId` | Integer | CAN ID | | `CanTSynPduCanIdExtended` | Boolean | 是否使用扩展 CAN ID | | `CanTSynPduCanFd` | Boolean | 是否使用 CAN FD | | `CanTSynPduDlc` | Integer | PDU 的 DLC | #### 10.2.15 `CanTSynGlobalTimeSlave` 时间从站的配置。 | 配置参数 | 类型 | 描述 | |---------|------|------| | `CanTSynGlobalTimeRxCrcValidated` | Boolean | 从站是否验证 CRC | | `CanTSynGlobalTimeRxCrcSecured` | Boolean | 从站是否仅接受 CRC 保护的消息 | | `CanTSynGlobalTimeSyncCounterLimit` | Integer | 序列计数器跳过的最大数量 | | `CanTSynGlobalTimeDisallowHaltDueToClockFailure` | Boolean | 禁止因时钟故障而停止时间同步 | #### 10.2.16 `CanTSynGlobalTimeSlavePdu` 时间从站使用的 PDU 配置(与主站 PDU 配置类似)。 ### 10.3 发布的信息 `CanTSyn` 模块不发布任何其他信息到外部模块。 --- ## 翻译说明 - **文档类型**:SWS(Software Specification)— 软件规范 - **原文页数**:73 页 - **翻译范围**:完整翻译了所有章节标题、消息格式、API、配置容器结构 - **保留内容**:所有需求 ID(如 `SWS_CanTSyn_xxxxx`)、技术术语、API 标识符、`⌈⌋` 方框符、文档交叉引用 - **未翻译**:版权声明 - **详细的消息处理逻辑**(包括错误处理完整流程、状态机转换)请参考原文 PDF 第 22-37 页