# SWS_CRCLibrary — CRC 例程规范 | 文档元信息 | 值 | |------------|------| | 文档标题 | Specification of CRC Routines(CRC 例程规范) | | 文档所有者 | AUTOSAR | | 文档责任方 | AUTOSAR | | 文档标识号 | 016 | | 文档状态 | Final(最终版) | | 所属 AUTOSAR 标准 | Classic Platform(经典平台) | | 所属标准发布版本 | 4.4.0 | | 发布版本 | AUTOSAR CP Release 4.4.0 | ## 文档变更历史 | 日期 | 发布版本 | 变更人 | 变更说明 | |------|----------|--------|----------| | 2018-10-31 | 4.4.0 | AUTOSAR Release Management | 引入多项式为 0x8005 的新 CRC-16;编辑性修改 | | 2017-12-08 | 4.3.1 | AUTOSAR Release Management | 编辑性修改 | | 2016-11-30 | 4.3.0 | AUTOSAR Release Management | 引入 E2E Profile 7 的新 CRC-64;编辑性修改 | | 2015-07-31 | 4.2.2 | AUTOSAR Release Management | 更正 CRC32 和 CRC32P4 的 magic check | | 2014-10-31 | 4.2.1 | AUTOSAR Release Management | 引入多项式为 0xF4ACFB13 的新 CRC-32;编辑性修改 | | 2014-03-31 | 4.1.3 | AUTOSAR Release Management | 更正 CRC32 IEEE 802.3 检查值;编辑性修改 | | 2013-10-31 | 4.1.2 | AUTOSAR Release Management | 编辑性修改;删除变更文档章节 | | 2013-03-15 | 4.1.1 | AUTOSAR Administration | 关于如何使用 CRC 例程的新示例及关于 CCITT 标准的说明;移除调试概念 | | 2011-12-22 | 4.0.3 | AUTOSAR Administration | GetVersionInfo API 始终可用 | | 2010-09-30 | 3.1.5 | AUTOSAR Administration | 添加新参数到 API 以链接 CRC 计算;更正 CRC 检查值并更好地解释检查值;添加 CRC magic check | | 2010-02-02 | 3.1.4 | AUTOSAR Administration | 引入多项式为 2Fh 的新 CRC-8;CRC-8 现在符合 SAE J1850;修订法律免责声明 | | 2008-08-13 | 3.1.1 | AUTOSAR Administration | 从内存服务需求中分离 CRC 需求;添加 CRC8 管理 | | 2008-02-01 | 3.0.2 | AUTOSAR Administration | 从内存服务需求中分离 CRC 需求;添加 CRC8 管理 | | 2007-12-21 | 3.0.1 | AUTOSAR Administration | 扩展文档元信息;进行小型布局调整 | | 2007-01-24 | 2.1.15 | AUTOSAR Administration | 修订"用户建议";添加"修订信息" | | 2006-11-28 | 2.1.1 | AUTOSAR Administration | Crc_CalculateCRC16 和 Crc_CalculateCRC32 API,Crc_DataPtr 参数:将 void 指针更改为 uint8 指针;修订法律免责声明 | | 2006-05-16 | 2.0 | AUTOSAR Administration | 文档结构适应通用发布 2.0 SWS 模板;引入 UML 模型;更新需求可追溯性;硬件支持 CRC 计算的可重入性 | | 2005-05-31 | 1.0 | AUTOSAR Administration | 初始发布 | --- ## 目录 1. [引言与功能概述](#1-引言与功能概述) 2. [缩略语与缩写](#2-缩略语与缩写) 3. [相关文档](#3-相关文档) - 3.1 [输入文档](#31-输入文档) - 3.2 [相关标准与规范](#32-相关标准与规范) 4. [约束与假设](#4-约束与假设) - 4.1 [局限性](#41-局限性) - 4.2 [对汽车领域的适用性](#42-对汽车领域的适用性) 5. [与其他模块的依赖关系](#5-与其他模块的依赖关系) 6. [需求可追溯性](#6-需求可追溯性) 7. [功能规范](#7-功能规范) - 7.1 [CRC 码基本概念](#71-crc-码基本概念) - 7.2 [标准参数](#72-标准参数) - 7.3 [一般行为](#73-一般行为) - 7.4 [错误分类](#74-错误分类) - 7.5 [错误检测](#75-错误检测) - 7.6 [错误通知](#76-错误通知) - 7.7 [版本检查](#77-版本检查) - 7.8 [调试概念](#78-调试概念) 8. [API 规范](#8-api-规范) - 8.1 [导入类型](#81-导入类型) - 8.2 [类型定义](#82-类型定义) - 8.3 [函数定义](#83-函数定义) - 8.4 [回调通知](#84-回调通知) - 8.5 [调度函数](#85-调度函数) - 8.6 [预期接口](#86-预期接口) 9. [时序图](#9-时序图) 10. [配置规范](#10-配置规范) - 10.1 [如何阅读本章](#101-如何阅读本章) - 10.2 [容器和配置参数](#102-容器和配置参数) - 10.3 [发布信息](#103-发布信息) 11. [不适用的需求](#11-不适用的需求) --- ## 1 引言与功能概述 本规范规定了 AUTOSAR 基本软件模块 CRC 的功能、API 和配置。 CRC 库包含以下用于 CRC 计算的例程: - **CRC8**:SAEJ1850 - **CRC8H2F**:CRC8 0x2F 多项式 - **CRC16** - **CRC32** - **CRC32P4**:CRC32 0x1F4ACFB13 多项式 - **CRC64**:CRC-64-ECMA 对于所有例程(CRC8、CRC8H2F、CRC16、CRC32、CRC32P4 和 CRC64),以下计算方法是可能的: - **基于表的计算**:执行速度快,但代码大小较大(ROM 表) - **运行时计算**:执行较慢,但代码大小较小(无 ROM 表) - **硬件支持的 CRC 计算**(设备特定):执行速度快,CPU 时间少 所有例程都是可重入的(re-entrant),可同时被多个应用程序使用。未来某些设备可能支持硬件支持的 CRC 计算。 ## 2 缩略语与缩写 具有局部范围、因此未包含在 AUTOSAR 词汇表中的缩略语和缩写必须出现在局部词汇表中。 | 缩写 | 描述 | |------|------| | **CRC** | Cyclic Redundancy Check(循环冗余校验) | | **ALU** | Arithmetic Logic Unit(算术逻辑单元) | ## 3 相关文档 ### 3.1 输入文档 - [1] List of Basic Software Modules, AUTOSAR_TR_BSWModuleList.pdf - [2] Layered Software Architecture, AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf - [3] General Requirements on Basic Software Modules, AUTOSAR_SRS_BSWGeneral.pdf - [4] Requirements on Libraries, AUTOSAR_SRS_Libraries.pdf - [5] Specification of ECU Configuration, AUTOSAR_TPS_ECUConfiguration.pdf - [6] A Painless Guide To CRC Error Detection Algorithms, Ross N. Williams - [7] Basic Software Module Description Template, AUTOSAR_TPS_BSWModuleDescriptionTemplate.pdf - [8] Specification of Platform Types, AUTOSAR_SWS_PlatformTypes.pdf - [9] Specification of Standard Types, AUTOSAR_SWS_StandardTypes.pdf - [10] Specification of C Implementation Rules, AUTOSAR_TR_CImplementationRules.pdf ### 3.2 相关标准与规范 - [11] SAE-J1850 8-bit CRC - [12] CCITT-FALSE 16-bit CRC,参考 ITU-T Recommendation X.25 (10/96) 第 2.2.7.4 节"帧检查序列(FCS)字段"和附录 I - [13] IEEE 802.3 Ethernet 32-bit CRC - [14] "32-Bit Cyclic Redundancy Codes for Internet Applications" [Koopman 2002] - [15] Wikipedia.org – listing of CRCs, including CRC-64-ECMA, https://en.wikipedia.org/wiki/Cyclic_redundancy_check ## 4 约束与假设 ### 4.1 局限性 无已知局限性。 ### 4.2 对汽车领域的适用性 无限制。 ## 5 与其他模块的依赖关系 与其他模块没有依赖关系。 ## 6 需求可追溯性 | 需求 | 描述 | 由以下需求满足 | |------|------|----------------| | SRS_BSW_00005 | MCAL 层的模块不得有硬编码的水平接口。 | SWS_Crc_00051 | | SRS_BSW_00006 | MCAL 层以上的软件模块的源代码不应是处理器和编译器相关的。 | SWS_Crc_00051 | | SRS_BSW_00007 | 所有用 C 语言编写的 BSW 模块应符合 MISRA C 2012 标准。 | SWS_Crc_00051 | | SRS_BSW_00009 | 所有 BSW 模块应按照通用标准进行文档化。 | SWS_Crc_00051 | | SRS_BSW_00010 | 所有 BSW 模块的内存消耗应针对所有支持平台的已定义配置进行文档化。 | SWS_Crc_00051 | | SRS_BSW_00101 | 基本软件模块应能够在单独的初始化函数中初始化变量和硬件。 | SWS_Crc_00051 | | SRS_BSW_00304 | 所有 AUTOSAR 基本软件模块应使用以下数据类型,而非原生 C 数据类型。 | SWS_Crc_00051 | | SRS_BSW_00305 | 数据类型命名约定。 | SWS_Crc_00051 | | SRS_BSW_00306 | AUTOSAR 基本软件模块应是编译器和平台无关的。 | SWS_Crc_00051 | | SRS_BSW_00312 | 共享代码应是可重入的。 | SWS_Crc_00051 | | SRS_BSW_00323 | 所有 AUTOSAR 基本软件模块应检查传递的 API 参数的有效性。 | SWS_Crc_00051 | | SRS_BSW_00348 | 所有 AUTOSAR 标准类型和常量应放置并组织在标准类型头文件中。 | SWS_Crc_00051 | | SRS_BSW_00378 | AUTOSAR 应提供 boolean 类型。 | SWS_Crc_00051 | | SRS_BSW_00407 | 每个 BSW 模块应提供读取专用模块实现版本信息的函数。 | SWS_Crc_00011, SWS_Crc_00017 | | SRS_BSW_00411 | 所有 AUTOSAR 基本软件模块应应用 API 存在启用/禁用的命名规则。 | SWS_Crc_00011, SWS_Crc_00017 | | SRS_LIBS_08518 | CRC 库应提供不同的计算方法,优化性能或内存使用。 | SWS_Crc_00065, SWS_Crc_00070 | | SRS_LIBS_08525 | CRC 库应支持标准生成多项式。 | SWS_Crc_00002, SWS_Crc_00003, SWS_Crc_00056, SWS_Crc_00057, SWS_Crc_00062, SWS_Crc_00063, SWS_Crc_00064, SWS_Crc_00067, SWS_Crc_00068, SWS_Crc_00069 | | SRS_LIBS_08526 | CRC 库应支持当前的 CRC 计算标准。 | SWS_Crc_00065, SWS_Crc_00070 | > 注:完整的需求追踪表(包含所有 BSW 需求)请参见原文 PDF。 ## 7 功能规范 ### 7.1 CRC 码基本概念 #### 7.1.1 数学描述 设 D 是数据的按位表示,总共 n 位,即: ``` D = (d_(n-1), d_(n-2), d_(n-3), …, d_1, d_0) ``` 其中 d_0, d_1, … = 0b, 1b。相应的冗余码 C 由 n+k 位表示为: ``` C = (D, R) = (d_(n-1), d_(n-2), d_(n-3), …, d_2, d_1, d_0, r_(k-1), …, r_2, r_1, r_0) ``` 其中 r_0, r_1, … = 0b, 1b,R = (r_(k-1), …, r_2, r_1, r_0)。该代码只是数据和冗余部分的简单串联。(对于我们的应用,我们将选择 k = 16、32 和 n 为 16 或 32 的倍数)。 CRC 算法与具有两个元素有限域中系数的多项式相关,使用根据下表的算术运算 ⊕ 和 *。 ⊕ 运算被识别为二进制异或运算,通常在任何 CPU 的 ALU 中都可用。 | ⊕ | 0b | 1b | | * | 0b | 1b | |----|----|----|--|----|----|----| | 0b | 0b | 1b | | 0b | 0b | 0b | | 1b | 1b | 0b | | 1b | 0b | 1b | 为简单起见,我们将写 ab 而不是 a*b。 我们介绍一些具有两个元素域中系数的多项式示例,并给出其简化表示。 (例 1)`p1(X) = 1b·X^3 + 0b·X^2 + 1b·X^1 + 0b·X^0 = X^3 + X` (例 2)`p2(X) = 1b·X^2 + 1b·X^1 + 1b·X^0 = X^2 + X^1 + 1b` 由 n+k 位表示的任何码字都可以映射到 n+k-1 阶的多项式,其系数在两个元素域中。我们使用位的直观映射,即: ``` C(X) = d_(n-1)·X^(k+n-1) + d_(n-2)·X^(k+n-2) + … + d_2·X^(k+2) + d_1·X^(k+1) + d_0·X^k + r_(k-1)·X^(k-1) + r_(k-2)·X^(k-2) + … r_1·X + r_0 ``` ``` C(X) = X^k·(d_(n-1)·X^(n-1) + d_(n-2)·X^(n-2) + … + d_2·X^2 + d_1·X^1 + d_0) + r_(k-1)·X^(k-1) + … ``` ``` C(X) = X^k·D(X) ⊕ R(X) ``` 此映射是一对一的。 某种循环冗余码多项式空间 CRCG 被定义为给定生成多项式 G(X) = X^k + g_(k-1)·X^(k-1) + g_(k-2)·X^(k-2) + … + g_2·X^2 + g_1·X + g_0 的倍数。根据定义,对于 CRCG 中的任何码多项式 C(X),存在一个多项式 M(X),使得: ``` C(X) = G(X)·M(X) ``` 对于固定的不可约(即素数)多项式 G(X),映射 M(X) → C(X) 是一对一的。现在如何验证给定码字的数据?这基本上是多项式的除法,使用欧几里得算法。在实践中,我们对 M(X) 不感兴趣,而是对除法的余数 C(X) mod G(X) 感兴趣。对于正确的码字 C,此余数必须为零,C(X) mod G(X) = 0。如果不是这样,则码字中存在错误。给定 G(X) 具有一些额外的代数属性,可以确定错误位置并纠正码字。 从数据计算码字也可以使用欧几里得算法完成。对于给定的数据多项式 D(x) = d_(n-1)·X^(n-1) + d_(n-2)·X^(n-2) + … + d_1·X^1 + d_0 和相应的码多项式 C(X),我们有: ``` C(X) = X^k·D(X) ⊕ R(X) = M(X)·G(X) ``` 对两边执行"mod G(X)"运算,得到: ``` 0 = C(X) mod G(X) = [X^k·D(X)] mod G(X) ⊕ R(X) mod G(X) (*) ``` 我们注意到多项式 R(X) 的阶小于 G(X) 的阶,因此模除法得到的余数为 R(X): ``` R(X) mod G(X) = R(X) ``` 对于在两个元素的有限域中具有系数的多项式 R(X),我们具有显著的性质 R(X) + R(X) = 0。如果我们在方程 (*) 两边加上 R(X),得到: ``` R(X) = X^k·D(X) mod G(X) ``` 重要的含义是所请求码的冗余部分可以通过使用多项式的欧几里得算法来确定。目前,任何 CRC 计算方法都是此基本算法的或多或少的复杂变体。 到目前为止,关于 CRC 码的命题总结如下: 1. CRC 码的构造原理基于两个元素有限域中具有系数的多项式。该域的 ⊕ 运算与二进制运算"xor"(异或)相同。 2. 存在从位序列到该多项式空间的自然映射。 3. CRC 码多项式的计算和验证均基于模给定生成多项式的除法。 4. 此生成多项式必须具有某些代数属性以实现错误检测和最终错误纠正。 #### 7.1.2 二元多项式和位序列的欧几里得算法 给定多项式 `Pn(X) = pn·X^n + p_(n-1)·X^(n-1) + … + p_2·X^2 + p_1·X + p_0`,其系数在两个元素的有限域中。设 `Q(X) = X^k + q_(k-1)·X^(k-1) + q_(k-2)·X^(k-2) + … + q_2·X^2 + q_1·X + q_0` 是另一精确阶 k>0 的多项式。设 `Rn(X)` 是多项式除法的最大阶 k-1 的余数,`Mn(X)` 相应地满足: ``` Rn(X) ⊕ Mn(X)·Q(X) = Pn(X) ``` **欧几里得算法 - 递归** (递归终止) 如果 n < k,则选择 Rn(X) = Pn(X) 和 Mn = 0。 (递归 n+1 → n) 设 P_(n+1)(X) 的最大阶为 n+1。 如果 n+1 >= k,则计算 `Pn(X) = P_(n+1)(X) - p_(n+1)·Q(X)·X^(n-k+1)`。此多项式的最大阶为 n。然后: ``` P_(n+1)(X) mod Q(X) = Pn(X) mod Q(X) ``` **递归证明** 选择 `R_(n+1)(X) = P_(n+1)(X) mod Q(X)` 和 `M_(n+1)(X)` 使得: ``` R_(n+1)(X) ⊕ M_(n+1)(X)·Q(X) = P_(n+1)(X) ``` 然后 `R_(n+1)(X) - Rn(X) = P_(n+1)(X) - M_(n+1)(X)·Q(X) - Pn(X) ⊕ Mn(X)·Q(X)`。 使用 `P_(n+1)(X) - Pn(X) = p_(n+1)·Q(X)·X^(n-k+1)`,我们得到: ``` R_(n+1)(X) - Rn(X) = p_(n+1)·Q(X)·X^(n-k+1) + Mn(X)·Q(X) - M_(n+1)(X)·Q(X) ``` ``` R_(n+1)(X) - Rn(X) = Q(X)·[p_(n+1)·X^(n-k+1) + Mn(X) - M_(n+1)(X)] ``` 左边是最大阶 k-1 的多项式。右边 Q(X) 的精确阶为 k。这意味着两边都是平凡的并等于零。我们得到: ``` R_(n+1)(X) = Rn(X) (1) M_(n+1)(X) = Mn(X) + p_(n+1)·X^(n-k+1) (2) ``` (证明结束) **示例:** `P(X) = P_4(X) = X^4 + X^2 + X + 1b; Q(X) = X^2 + X + 1b; n = 4; k = 2` ``` P_3(X) = X^4 + X^2 + X + 1b - 1b·(X^2 + X + 1b)·X^2 = X^3 + X + 1b P_2(X) = X^3 + X + 1b - 1b·X·(X^2 + X + 1b) = X^2 + 1b P_1(X) = X^2 + 1 - 1b·(X^2 + X + 1) = X R(X) = P(X) mod Q(X) = R_1(X) = P_1(X) = X ``` #### 7.1.3 CRC 计算、变体和参数 基于欧几里得算法,已经开发了一些变体以提高计算性能。所有这些变体都不会提高检测或纠正错误的能力——结果码的所谓海明距离仅由生成多项式决定。变体仅针对不同实现的 ALU 进行优化。 CRC 计算方法的特征如下: 1. 数据到位序列 (d_(n-1), d_(n-2), d_(n-3), …, d_1, d_0) 的映射规则以及相应的数据多项式 D(X)(标准或反射数据)。 2. 生成多项式 G(X) 3. 起始值和相应的多项式 S(X) 4. 附录 A(X),也称为用于修改最终结果的 XOR 值。 5. 将结果 CRC 余数 R(X) 映射到码字的规则(标准或反射数据) 计算本身按以下步骤组织: - 将数据映射到 D(X) - 对 `X^k·D(X) + X^(n-k-1)·S(X) + A(X)` 执行欧几里得算法,并确定 `R(X) = [X^k·D(X) + X^(n-k-1)·S(X) + A(X)] mod G(X)` - 将 D(X)、R(X) 映射到码字 ### 7.2 标准参数 本节给出了通常用于 8 位、16 位和 32 位 CRC 计算的标准参数的粗略概述。 - **CRC result width(CRC 结果宽度)**:定义 CRC 计算的结果数据宽度。 - **Polynomial(多项式)**:定义用于 CRC 算法的生成多项式。 - **Initial value(初始值)**:定义 CRC 算法的起始条件。 - **Input data reflected(输入数据反射)**:定义在处理前是否反射每个输入字节的位(参见下面的定义)。 - **Result data reflected(结果数据反射)**:类似于"输入数据反射",此参数定义是否反射 CRC 结果的位(参见下面的定义)。结果在 CRC8 上通过 8 位反射,在 CRC16 上通过 16 位反射,在 CRC32 上通过 32 位反射。 - **XOR value(XOR 值)**:在将值作为官方校验和返回之前,该值与最终寄存器值进行 XOR 运算。 - **Check(检查值)**:此字段是检查值,可用作算法实现的弱验证器。该字段包含当 ASCII 值 '1' '2' '3' '4' '5' '6' '7' '8' '9'(对应于值 31h 32h 33h 34h 35h 36h 37h 38h 39h)通过指定算法馈送时获得的校验和。 - **Magic check(魔术检查)**:CRC 检查过程计算整个数据块(包括 CRC 结果)的 CRC。无错误的数据块将始终导致唯一的常数多项式(magic check)——表示 CRC 结果与 'XOR value' 进行 XOR 运算的结果——无论数据块内容如何。 **Magic check 示例**:对数据字节 00h 00h 00h 00h 计算 SAE-J1850 CRC8(详细参数见 SWS_Crc_00030): - CRC 生成:00h 00h 00h 00h 上的 CRC,起始值 FFh: - CRC-result = 59h - CRC 检查:00h 00h 00h 00h 59h 上的 CRC,起始值 FFh: - CRC-result = 3Bh - Magic check = CRC-result 与 'XOR value' 异或: - C4h = 3Bh xor FFh **数据反射**:它是对位基础的反射,其中数据位以相反的顺序写入。公式为: 其中 x 是数据,n 是数据位数。 例如:reflection8 of 2D16 (n=8) (00101101_2) 是 B416 (10110100_2) reflection16 of 1234567816 (n=16) (0001 0010 0011 0100 0101 0110 0111 1000_2) 是 1E6A2C4816 (0001 1110 0110 1010 0010 1100 0100 1000_2) reflection32 of 123456789ABCDEF0 (n=32) 是 0F7B3D591E6A2C4816 reflection8 of 123456789ABCDEF0 (n=8) 是 84C2A6E195D3B7F016 #### 7.2.1 8 位 CRC 计算 ##### 7.2.1.1 8 位 SAE J1850 CRC 计算 [SWS_Crc_00030] ⌈ CRC 模块的 `Crc_CalculateCRC8()` 函数应实现基于 SAE-J1850 CRC8 标准的 CRC8 例程: | 参数 | 值 | |------|-----| | CRC result width | 8 bits | | Polynomial | 1Dh | | Initial value | FFh | | Input data reflected | No | | Result data reflected | No | | XOR value | FFh | | Check | 4Bh | | Magic check | C4h | ⌋() [SWS_Crc_00052] ⌈ CRC 模块的 `Crc_CalculateCRC8()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|-----| | 00 00 00 00 | 59 | | F2 01 83 | 37 | | 0F AA 00 55 | 79 | | 00 FF 55 11 | B8 | | 33 22 55 AA BB CC DD EE FF | CB | | 92 6B 55 | 8C | | FF FF FF FF | 74 | ⌋() ##### 7.2.1.2 8 位 0x2F 多项式 CRC 计算 [SWS_Crc_00042] ⌈ CRC 模块的 `Crc_CalculateCRC8H2F()` 函数应实现基于生成多项式 0x2F 的 CRC8 例程: | 参数 | 值 | |------|-----| | CRC result width | 8 bits | | Polynomial | 2Fh | | Initial value | FFh | | Input data reflected | No | | Result data reflected | No | | XOR value | FFh | | Check | DFh | | Magic check | 42h | ⌋() [SWS_Crc_00053] ⌈ CRC 模块的 `Crc_CalculateCRC8H2F()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|-----| | 00 00 00 00 | 12 | | F2 01 83 | C2 | | 0F AA 00 55 | C6 | | 00 FF 55 11 | 77 | | 33 22 55 AA BB CC DD EE FF | 11 | | 92 6B 55 | 33 | | FF FF FF FF | 6C | ⌋() #### 7.2.2 16 位 CRC 计算 ##### 7.2.2.1 16 位 CCITT-FALSE CRC16 [SWS_Crc_00002] ⌈ CRC 模块应实现基于 CCITT-FALSE CRC16 标准的 CRC16 例程: > **注意关于标准文档 [8]:** > 当构建帧时(即 CCITT-FALSE CRC16 的第一补码),计算的 FCS 等于 CRC16 XOR FFFFh。 > 对于验证,对相同的数据 + FCS 计算 CRC16(CCITT-FALSE),结果值始终为 1D0Fh。 > 注意,如果在验证期间,对数据 + CRC16(即 FCS XOR FFFFh)进行检查,则结果值将为 0000h,这是 CCITT-FALSE magic check。 | 参数 | 值 | |------|-----| | CRC result width | 16 bits | | Polynomial | 1021h | | Initial value | FFFFh | | Input data reflected | No | | Result data reflected | No | | XOR value | 0000h | | Check | 29B1h | | Magic check | 0000h | ⌋(SRS_LIBS_08525) [SWS_Crc_00054] ⌈ CRC 模块的 `Crc_CalculateCRC16()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|------| | 00 00 00 00 | 84C0 | | F2 01 83 | D374 | | 0F AA 00 55 | 2023 | | 00 FF 55 11 | B8F9 | | 33 22 55 AA BB CC DD EE FF | F53F | | 92 6B 55 | 0745 | | FF FF FF FF | 1D0F | ⌋() ##### 7.2.2.2 16 位 0x8005 多项式 CRC 计算 [SWS_Crc_00067] ⌈ CRC 模块应实现基于 CRC-16/ARC 标准的 CRC16: | 参数 | 值 | |------|-----| | CRC result width | 16 bits | | Polynomial | 8005h | | Initial value | 0000h | | Input data reflected | Yes | | Result data reflected | Yes | | XOR value | 0000h | | Check | BB3Dh | | Magic check | 0000h | ⌋(SRS_LIBS_08525) [SWS_Crc_00068] ⌈ CRC 模块的 `Crc_CalculateCRC16ARC()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|------| | 00 00 00 00 | 0000 | | F2 01 83 | C2E1 | | 0F AA 00 55 | 0BE3 | | 00 FF 55 11 | 6CCF | | 33 22 55 AA BB CC DD EE FF | AE98 | | 92 6B 55 | E24E | | FF FF FF FF | 9401 | ⌋(SRS_LIBS_08525) #### 7.2.3 32 位 CRC 计算 ##### 7.2.3.1 32 位以太网 CRC 计算 [SWS_Crc_00003] ⌈ CRC 模块应实现基于 IEEE-802.3 CRC32 以太网标准的 CRC32 例程: | 参数 | 值 | |------|-----| | CRC result width | 32 bits | | Polynomial | 04C11DB7h | | Initial value | FFFFFFFFh | | Input data reflected | Yes | | Result data reflected | Yes | | XOR value | FFFFFFFFh | | Check | CBF43926h | | Magic check* | DEBB20E3h | > **\* 重要说明**:为了匹配 magic check 值,CRC 必须以小端格式附加,即低有效字节优先。这是由于输入和结果的反射。 ⌋(SRS_LIBS_08525) [SWS_Crc_00055] ⌈ CRC 模块的 `Crc_CalculateCRC32()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|-----------| | 00 00 00 00 | 2144DF1C | | F2 01 83 | 24AB9D77 | | 0F AA 00 55 | B6C9B287 | | 00 FF 55 11 | 32A06212 | | 33 22 55 AA BB CC DD EE FF | B0AE863D | | 92 6B 55 | 9CDEA29B | | FF FF FF FF | FFFFFFFF | ⌋() ##### 7.2.3.2 32 位 0xF4ACFB13 多项式 CRC 计算 此 32 位 CRC 函数在 [14] 中描述。相对于以太网 CRC,它具有优势——它对 4kB 以下的数据具有 6 的海明距离。 [SWS_Crc_00056] ⌈ CRC 模块应使用 `0x1'F4'AC'FB'13`(`0xF4'AC'FB'13`)多项式实现 CRC32 例程: | 参数 | 值 | |------|-----| | CRC result width | 32 bits | | Polynomial | F4'AC'FB'13h | | Initial value | FFFFFFFFh | | Input data reflected | Yes | | Result data reflected | Yes | | XOR value | FFFFFFFFh | | Check | 16'97'D0'6Ah | | Magic check* | 90'4C'DD'BFh | | Hamming distance | 6, up to 4096 bytes (including CRC) | > **\* 重要说明**:为了匹配 magic check 值,CRC 必须以小端格式附加,即低有效字节优先。这是由于输入和结果的反射。 ⌋(SRS_LIBS_08525) 有三种编码多项式的表示法,为澄清起见,列出所有三种表示法: | # | 表示法 | 值 | |---|--------|-----| | 1 | 多项式为二进制 | 0001`1111`0100`1010`1100`1111`1011`0001`0011 | | 2 | 正常表示法(高位) | 01'F4'AC'FB'13h | | 3 | 正常表示法 | F4'AC'FB'13h | | 4 | 反向互逆表示法(= Koopman 表示法) | FA'56'7D'89h | **注意:** 1. 正常表示法(高位)= 多项式的十六进制表示为二进制 2. 正常表示法(高位)= Koopman 表示法 * 2 + 1 [SWS_Crc_00057] ⌈ CRC 模块的 `Crc_CalculateCRC32P4()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|----------| | 00 00 00 00 | 6FB32240h | | F2 01 83 | 4F721A25h | | 0F AA 00 55 | 20662DF8h | | 00 FF 55 11 | 9BD7996Eh | | 33 22 55 AA BB CC DD EE FF | A65A343Dh | | 92 6B 55 | EE688A78h | | FF FF FF FF | FFFFFFFFh | ⌋(SRS_LIBS_08525) #### 7.2.4 64 位 CRC 计算 ##### 7.2.4.1 64 位 ECMA 多项式 CRC 计算 此 64 位 CRC 函数在 [15] 中描述。它对于长数据具有 4 的良好海明距离(见下文)。 [SWS_Crc_00062] ⌈ CRC 模块应使用 `0x1'42'F0'E1'EB'A9'EA'36'93`(`0x42'F0'E1'EB'A9'EA'36'93`)多项式实现 CRC64 例程: | 参数 | 值 | |------|-----| | CRC result width | 64 bits | | Polynomial | 42'F0'E1'EB'A9'EA'36'93h | | Initial value | FFFFFFFFFFFFFFFFh | | Input data reflected | Yes | | Result data reflected | Yes | | XOR value | FFFFFFFFFFFFFFFFh | | Check | 99'5D'C9'BB'DF'19'39'FAh | | Magic check* | 49'95'8C'9A'BD'7D'35'3Fh | | Hamming distance | 4, up to almost 8 GB | > **\* 重要说明**:为了匹配 magic check 值,CRC 必须以小端格式附加,即低有效字节优先。这是由于输入和结果的反射。 ⌋(SRS_LIBS_08525) 有三种编码多项式的表示法,为澄清起见,列出所有三种表示法: | # | 表示法 | 值 | |---|--------|-----| | 1 | 多项式为二进制 | 0001'0100'0010'1111'0000'1110'0001'1110'1011'1010'1001'1110'1010'0011'0110'1001'0011 | | 2 | 正常表示法(高位) | 01'42'F0'E1'EB'A9'EA'36'93h | | 3 | 正常表示法 | 42'F0'E1'EB'A9'EA'36'93h | | 4 | 反向互逆表示法(= Koopman 表示法) | A1'78'70'F5'D4'F5'1B'49h | [SWS_Crc_00063] ⌈ CRC 模块的 `Crc_CalculateCRC64()` 函数应提供以下 CRC 结果: | 数据字节(十六进制) | CRC | |----------------------|----------| | 00 00 00 00 | F4A586351E1B9F4Bh | | F2 01 83 | 319C27668164F1C6h | | 0F AA 00 55 | 54C5D0F7667C1575h | | 00 FF 55 11 | A63822BE7E0704E6h | | 33 22 55 AA BB CC DD EE FF | 701ECEB219A8E5D5h | | 92 6B 55 | 5FAA96A9B59F3E4Eh | | FF FF FF FF | FFFFFFFF00000000h | ⌋(SRS_LIBS_08525) ### 7.3 一般行为 数据块通过参数"起始地址"、"大小"和"起始值"传递给 CRC 例程。返回值是 CRC 结果。 ### 7.4 错误分类 CRC 库函数不提供任何错误分类。CRC 重新计算和比较必须由上层的每个模块(例如 NVRAM Manager)完成。 ### 7.5 错误检测 CRC 库函数不提供任何错误检测机制。 ### 7.6 错误通知 CRC 库函数不提供任何错误通知。 ### 7.7 版本检查 有关详细信息,请参阅 SWS_BSWGeneral 中的第 5.1.8 章"版本检查"。 ### 7.8 调试概念 无。 ## 8 API 规范 ### 8.1 导入类型 本章列出从以下模块包含的所有类型: [SWS_Crc_00018] ⌈ | 模块 | 头文件 | 导入类型 | |------|--------|----------| | Std_Types | StandardTypes.h | Std_VersionInfoType | ⌋() ### 8.2 类型定义 无。 ### 8.3 函数定义 [SWS_Crc_00013] ⌈ 如果 CRC 例程要用作库,CRC 模块的实施者应以只有其他模块使用的 CRC 代码部分链接到最终二进制的方式来开发 CRC 模块。 ⌋() [SWS_Crc_00014] ⌈ CRC 函数(参数 `Crc_IsFirstCall = TRUE`)应执行以下操作: 1. 作为 CRC 计算的"初始值",使用多项式的属性"初始值": ``` Crc = PolynomialInitVal ``` 2. 如果多项式的属性"输入数据反射"为 TRUE,则反射通过参数 `Crc_DataPtr` 和 `Crc_Length` 获得的输入数据(逐字节): ``` Data = reflect8(Data) // 当"输入数据反射"为 TRUE 时 ``` 3. 对数据、上一个 CRC 和 CRC 多项式计算 CRC: ``` Crc = f(Data, Crc, Polynomial) ``` 4. 在 crc 和多项式的"XOR 值"之间执行 XOR 运算: ``` Crc = Crc ^ PolynomialXorVal ``` 5. 如果多项式的属性"结果数据反射"为 TRUE,则反射 CRC(通过 8、16 或 32 位,取决于 CRC 大小): ``` Crc = reflectCrc size(Crc) // 当"结果数据反射"为 TRUE 时 ``` 6. 返回 CRC: ``` return Crc ``` 只要数据可用,就执行步骤 2 和 3。 [SWS_Crc_00041] ⌈ CRC 函数(参数 `Crc_IsFirstCall = FALSE`)应执行以下操作: 1. 作为 CRC 计算的"初始值",使用参数 `Crc_StartValueX`(X 为 8、8H2F、16、32、P4 或 64),它应该是上一次调用的 CRC 结果。然后结果与"XOR 值"进行 XOR 运算,如果多项式的"结果数据反射"为 TRUE,则反射: ``` Crc = Crc_StartValueX ^ PolynomialXorVal Crc = reflectCrc size(Crc) // 当"结果数据反射"为 TRUE 时 ``` 步骤 2 至 6 与 [SWS_Crc_00014] 相同。 ⌋() **CRC 函数的使用:** 对于第一次或唯一的调用,CRC 函数的用户应: 1. 提供指向数据的指针(`Crc_DataPtr`) 2. 提供数据的字节数(`Crc_Length`) 3. 给 `Crc_StartValueX` 参数一个 don't care 值(初始化值由所选算法已知) 4. 给 `Crc_IsFirstCall` 参数值 TRUE 以通知库这是第一次或唯一的调用 5. 调用 CRC 函数 6. 获取 CRC 对于后续调用,用户必须: 1. 提供指向数据的指针(`Crc_DataPtr`) 2. 提供数据的字节数(`Crc_Length`) 3. 给 `Crc_StartValueX` 参数(X 为 8、8H2F、16、32、P4 或 64)上一次调用的 CRC 结果 4. 给 `Crc_IsFirstCall` 参数值 FALSE 以通知库这不是第一次调用 5. 调用 CRC 函数 6. 获取 CRC **示例 1**:计算 CRC8:计算 CRC8 SAEJ1850,使用 SAE J1850 规范定义的测试模式之一(00h、FFh、55h、11h 结果为 CRC B8h): ```c // 一步完成: uint8 Array[4] = {0x00, 0xFF, 0x55, 0x11}; uint8 ignored_val = 0x00; /* 任何值,都被忽略 */ uint8 resultSAE = Crc_CalculateCRC8(&Array[0], 4, ignored_val, TRUE); // resultSAE 应等于 B8h // 分多步完成: uint8 Array[4] = {0x00, 0xFF, 0x55, 0x11}; uint8 ignored_val = 0x00; uint8 resultSAE = Crc_CalculateCRC8(&Array[0], 2, ignored_val, TRUE); resultSAE = Crc_CalculateCRC8(&Array[2], 1, resultSAE, FALSE); resultSAE = Crc_CalculateCRC8(&Array[3], 1, resultSAE, FALSE); // resultSAE 也应等于 B8h ``` **示例 2**:计算 CRC8:与 SAE J1850 不兼容,但与 R4.0 之前的 AUTOSAR 版本兼容: ```c // 一步完成: uint8 Array[4] = {0x00, 0xFF, 0x55, 0x11}; // 第一次调用也获得 IsFirstCall 设置为 FALSE 和 0xFF 作为起始值, // CalculateCRC8 立即与 0xFF 进行 XOR,结果起始值等于 0x00。 uint8 resultRel3 = Crc_CalculateCRC8(&Array[0], 4, 0xFF, FALSE); // 最后的 XOR 必须被调用方否定,以达到 0x00 XOR value。 resultRel3 = resultRel3 ^ 0xFF; // resultRel3 包含与 AUTOSAR R3.2 CRC8 计算的值相同。 ``` **示例 3**:对数据字节 01h 02h 03h 04h 05h 06h 07h 08h 计算 CRC32 以太网标准(详细参数见 SWS_Crc_00003): - 在一个函数调用中,对 01h 02h 03h 04h 05h 06h 07h 08h 的 CRC,起始值 FFFFFFFFh: - CRC-result = 3FCA88C5h(最终值) - 在两个函数调用中: - 对 01h 02h 03h 04h 的 CRC,起始值 FFFFFFFFh: - CRC-result 第一次调用 = B63CFBCDh(中间值) - 对 05h 06h 07h 08h 的 CRC,起始值 B63CFBCDh xor XOR value(FFFFFFFFh)= 49C30432h,反射后:4C20C392h: - CRC-result 最终调用 = 3FCA88C5h(最终值) 以下 C 代码示例显示调用方使用前一个结果(无任何重做)修改起始值,并表明它不再是第一次调用: ```c InterResult = Crc_CalculateCRC32(&Array12345678[0], 4, 0xFFFFFFFF, TRUE); result = Crc_CalculateCRC32(&Array12345678[4], 4, InterResult, FALSE); ``` #### 8.3.1 8 位 CRC 计算 ##### 8.3.1.1 8 位 SAE J1850 CRC 计算 [SWS_Crc_00031] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC8` | | 语法 | `uint8 Crc_CalculateCRC8(const uint8* Crc_DataPtr, uint32 Crc_Length, uint8 Crc_StartValue8, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x01 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr` 指向要计算的数据块起始地址的指针;`Crc_Length` 要计算的数据块长度(以字节为单位);`Crc_StartValue8` 算法开始时的起始值;`Crc_IsFirstCall` TRUE:序列中的第一次调用或单个 CRC 计算;从初始值开始,忽略 `Crc_StartValue8`。FALSE:调用序列中的后续调用;`Crc_StartValue8` 被解释为前一个函数调用的返回值。 | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint8` CRC 计算的 8 位结果 | | 描述 | 此服务使用 SAE J1850 参数对 `Crc_Length` 数据字节进行 CRC8 计算。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00032] ⌈ 函数 `Crc_CalculateCRC8` 应使用 `Crc_StartValue8` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节执行 CRC8 计算。 ⌋() [SWS_Crc_00033] ⌈ 如果函数 `Crc_CalculateCRC8` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋() > **注意**:如果必须计算大数据块(> 32 字节,取决于处理器平台性能),应为函数 `Crc_CalculateCRC8` 配置基于表的计算方法以减少计算时间。 函数 `Crc_CalculateCRC8` 需要 ECUC_Crc_00006 中定义的配置参数的规范。 ##### 8.3.1.2 8 位 0x2F 多项式 CRC 计算 [SWS_Crc_00043] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC8H2F` | | 语法 | `uint8 Crc_CalculateCRC8H2F(const uint8* Crc_DataPtr, uint32 Crc_Length, uint8 Crc_StartValue8H2F, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x05 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr` 指向要计算的数据块起始地址的指针;`Crc_Length` 要计算的数据块长度(以字节为单位);`Crc_StartValue8H2F` 算法开始时的起始值;`Crc_IsFirstCall` TRUE:序列中的第一次调用或单个 CRC 计算;从初始值开始,忽略 `Crc_StartValue8H2F`。FALSE:调用序列中的后续调用;`Crc_StartValue8H2F` 被解释为前一个函数调用的返回值。 | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint8` CRC 计算的 8 位结果 | | 描述 | 此服务对 `Crc_Length` 数据字节使用多项式 0x2F 进行 CRC8 计算。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00044] ⌈ 函数 `Crc_CalculateCRC8H2F` 应使用 `Crc_StartValue8H2F` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节使用多项式 0x2F 执行 CRC8 计算。 ⌋() [SWS_Crc_00045] ⌈ 如果函数 `Crc_CalculateCRC8H2F` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋() > **注意**:如果必须计算大数据块(> 32 字节),应为函数 `Crc_CalculateCRC8H2F` 配置基于表的计算方法。 函数 `Crc_CalculateCRC8H2F` 需要 ECUC_Crc_00006 中定义的配置参数的规范。 #### 8.3.2 16 位 CRC 计算 ##### 8.3.2.1 16 位 CCITT-FALSE CRC16 [SWS_Crc_00019] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC16` | | 语法 | `uint16 Crc_CalculateCRC16(const uint8* Crc_DataPtr, uint32 Crc_Length, uint16 Crc_StartValue16, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x02 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr`、`Crc_Length`、`Crc_StartValue16`、`Crc_IsFirstCall` | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint16` CRC 计算的 16 位结果 | | 描述 | 此服务对 `Crc_Length` 数据字节进行 CRC16 计算。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00015] ⌈ 函数 `Crc_CalculateCRC16` 应使用 `Crc_StartValue16` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节执行 CRC16 计算。 ⌋() [SWS_Crc_00009] ⌈ 如果函数 `Crc_CalculateCRC16` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋() > **注意**:如果必须计算大数据块(> 32 字节),应为函数 `Crc_CalculateCRC16` 配置基于表的计算方法。 函数 `Crc_CalculateCRC16` 需要 ECUC_Crc_00006 中定义的配置参数的规范。 ##### 8.3.2.2 16 位 0x8005 多项式 CRC 计算 [SWS_Crc_00071] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC16ARC` | | 语法 | `uint16 Crc_CalculateCRC16ARC(const uint8* Crc_DataPtr, uint32 Crc_Length, uint16 Crc_StartValue16, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x08 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr`、`Crc_Length`、`Crc_StartValue16`、`Crc_IsFirstCall` | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint16` CRC 计算的 16 位结果 | | 描述 | 此服务对 `Crc_Length` 数据字节使用多项式 0x8005 进行 CRC16 计算。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00069] ⌈ 函数 `Crc_CalculateCRC16ARC` 应使用 `Crc_StartValue16` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节使用多项式 0x8005 执行 CRC16 计算。 ⌋(SRS_LIBS_08525) [SWS_Crc_00070] ⌈ 如果函数 `Crc_CalculateCRC16ARC` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋(SRS_LIBS_08518, SRS_LIBS_08526) 函数 `Crc_CalculateCRC16ARC` 需要 ECUC_Crc_00035 中定义的配置参数的规范。 #### 8.3.3 32 位 CRC 计算 ##### 8.3.3.1 32 位以太网 CRC 计算 [SWS_Crc_00020] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC32` | | 语法 | `uint32 Crc_CalculateCRC32(const uint8* Crc_DataPtr, uint32 Crc_Length, uint32 Crc_StartValue32, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x03 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr`、`Crc_Length`、`Crc_StartValue32`、`Crc_IsFirstCall` | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint32` CRC 计算的 32 位结果 | | 描述 | 此服务对 `Crc_Length` 数据字节进行 CRC32 计算。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00016] ⌈ 函数 `Crc_CalculateCRC32` 应使用 `Crc_StartValue32` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节执行 CRC32 计算。 ⌋() [SWS_Crc_00010] ⌈ 如果函数 `Crc_CalculateCRC32` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋() 函数 `Crc_CalculateCRC32` 需要 ECUC_Crc_00006 中定义的配置参数的规范。 ##### 8.3.3.2 32 位 0xF4ACFB13 多项式 CRC 计算 [SWS_Crc_00058] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC32P4` | | 语法 | `uint32 Crc_CalculateCRC32P4(const uint8* Crc_DataPtr, uint32 Crc_Length, uint32 Crc_StartValue32, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x06 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr`、`Crc_Length`、`Crc_StartValue32`、`Crc_IsFirstCall` | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint32` CRC 计算的 32 位结果 | | 描述 | 此服务对 `Crc_Length` 数据字节使用多项式 0xF4ACFB13 进行 CRC32 计算。此 CRC 例程由 E2E Profile 4 使用。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00059] ⌈ 函数 `Crc_CalculateCRC32P4` 应使用 `Crc_StartValue32` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节使用多项式 0xF4ACFB13 执行 CRC32 计算。 ⌋() [SWS_Crc_00060] ⌈ 如果函数 `Crc_CalculateCRC32P4` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋() 函数 `Crc_CalculateCRC32P4` 需要 ECUC_Crc_00006 中定义的配置参数的规范。 #### 8.3.4 64 位 CRC 计算 ##### 8.3.4.1 64 位 0x42F0E1EBA9EA3693 多项式 CRC 计算 [SWS_Crc_00061] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_CalculateCRC64` | | 语法 | `uint64 Crc_CalculateCRC64(const uint8* Crc_DataPtr, uint32 Crc_Length, uint64 Crc_StartValue64, boolean Crc_IsFirstCall)` | | 服务 ID[hex] | 0x07 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | `Crc_DataPtr`、`Crc_Length`、`Crc_StartValue64`、`Crc_IsFirstCall` | | 参数 (in-out) | 无 | | 参数 (out) | 无 | | 返回值 | `uint64` CRC 计算的 64 位结果 | | 描述 | 此服务对 `Crc_Length` 数据字节使用多项式 0x42F0E1EBA9EA3693 进行 CRC64 计算。此 CRC 例程由 E2E Profile 7 使用。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00064] ⌈ 函数 `Crc_CalculateCRC64` 应使用 `Crc_StartValue64` 的起始值对 `Crc_DataPtr` 指向的 `Crc_Length` 数据字节使用多项式 0x42F0E1EBA9EA3693 执行 CRC64 计算。 ⌋(SRS_LIBS_08525) [SWS_Crc_00065] ⌈ 如果函数 `Crc_CalculateCRC64` 中的 CRC 计算由硬件执行,则 CRC 模块的实施者应通过实现(基于软件的)锁定机制来确保此函数的可重入性。 ⌋(SRS_LIBS_08518, SRS_LIBS_08526) 函数 `Crc_CalculateCRC64` 需要 ECUC_Crc_00006 中定义的配置参数的规范。 #### 8.3.5 Crc_GetVersionInfo [SWS_Crc_00021] ⌈ | 项 | 内容 | |----|------| | 服务名称 | `Crc_GetVersionInfo` | | 语法 | `void Crc_GetVersionInfo(Std_VersionInfoType* Versioninfo)` | | 服务 ID[hex] | 0x04 | | 同步/异步 | 同步 | | 可重入性 | 可重入 | | 参数 (in) | 无 | | 参数 (in-out) | 无 | | 参数 (out) | `Versioninfo` 指向存储此模块版本信息的位置 | | 返回值 | 无 | | 描述 | 此服务返回此模块的版本信息。 | | 通过 | Crc.h | ⌋() [SWS_Crc_00011] ⌈ 函数 `Crc_GetVersionInfo` 应返回 CRC 模块的版本信息。版本信息包括: - Module Id(模块 ID) - Vendor Id(供应商 ID) - Vendor specific version numbers(供应商特定版本号)(SRS_BSW_00407) ⌋(SRS_BSW_00407, SRS_BSW_00411) [SWS_Crc_00017] ⌈ 如果 `Crc_GetVersionInfo` 函数的调用方和被调用方的源代码都可用,CRC 模块应将此函数实现为宏,在模块头文件中定义。 ⌋(SRS_BSW_00407, SRS_BSW_00411) ### 8.4 回调通知 无。 ### 8.5 调度函数 本章列出了由基本软件模块调度器直接调用的所有函数。CRC 模块没有调度函数。 ### 8.6 预期接口 本章列出了从其他模块所需的所有接口。 #### 8.6.1 强制接口 无。 #### 8.6.2 可选接口 无。 #### 8.6.3 可配置接口 无。 ## 9 时序图 ### 9.1 Crc_CalculateCRC8() 下图显示了同步函数调用 `Crc_CalculateCRC8`。 ``` :User «module» :Crc | |--- Crc_CalculateCRC8(...) ----> | | Crc_CalculateCRC8() |<------------- (synchronous return) -------| ``` **描述:** `Crc_CalculateCRC8()` 同步执行。结果在函数调用中返回。 ### 9.2 Crc_CalculateCRC8H2F() 下图显示了同步函数调用 `Crc_CalculateCRC8H2F`。 **描述:** `Crc_CalculateCRC8H2F()` 同步执行。结果在函数调用中返回。 ### 9.3 Crc_CalculateCRC16() 下图显示了同步函数调用 `Crc_CalculateCRC16`。 **描述:** `Crc_CalculateCRC16/32()` 同步执行。结果随函数调用返回。 ### 9.4 Crc_CalculateCRC16ARC() 下图显示了同步函数调用 `Crc_CalculateCRC16ARC`。 **描述:** `Crc_CalculateCRC16ARC()` 同步执行。结果随函数调用返回。 ### 9.5 Crc_CalculateCRC32() 下图显示了同步函数调用 `Crc_CalculateCRC32`。 **描述:** `Crc_CalculateCRC16/32()` 同步执行。结果随函数调用返回。 ### 9.6 Crc_CalculateCRC32P4() 下图显示了同步函数调用 `Crc_CalculateCRC32P4`。 **描述:** `Crc_CalculateCRC32P4()` 同步执行。结果随函数调用返回。 ### 9.7 Crc_CalculateCRC64() 下图显示了同步函数调用 `Crc_CalculateCRC64`。 **描述:** `Crc_CalculateCRC64()` 同步执行。结果随函数调用返回。 ## 10 配置规范 ### 10.1 如何阅读本章 除本节外,强烈建议阅读以下文档: - AUTOSAR 分层架构 [2] - AUTOSAR ECU 配置规范 [5] 本节仅是关于该主题的简短概述,不会替代 ECU 配置规范文档。 #### 10.1.1 配置和配置参数 配置参数定义了模块实现的通用部分的可变性。这意味着只有通用或可配置的模块实现可以在系统和/或 ECU 配置期间适应使用中的环境(软件/硬件)。 配置参数的配置可以在软件过程中的不同时间实现:编译时之前、链接时之前或构建时之后。在下文中,应使用术语"配置类"(参数的)以指代配置点。 #### 10.1.2 容器 容器结构化了配置参数的集合。这意味着: - 所有配置参数都保存在容器中。 - (子)容器可以引用(子)容器。可以为这些引用分配多重性。多重性定义了所包含参数的可能实例数。 ### 10.2 容器和配置参数 以下各章总结了所有配置参数。参数的详细含义在第 7 章和第 8 章中描述。 #### 10.2.1 Crc | SWS Item | ECUC_Crc_00033 | |---------|----------------| | Module Name | Crc | | Module Description | Crc(Crc 例程)模块的配置。 | | Post-Build Variant Support | false | | Supported Config Variants | VARIANT-PRE-COMPILE | | Container Name | Multiplicity | Scope / Dependency | |----------------|--------------|---------------------| | CrcGeneral | 1 | CRC 模块的常规配置 | #### 10.2.2 CrcGeneral | SWS Item | ECUC_Crc_00006 | |---------|----------------| | Container Name | CrcGeneral | | Description | CRC 模块的常规配置 | **配置参数:** | 名称 | 描述 | 范围 | |------|------|------| | **Crc8Mode** (ECUC_Crc_00030) | 开关以选择可用的 CRC 8 位(SAE J1850)计算方法之一 | CRC_8_HARDWARE:基于硬件的 CRC8 计算;CRC_8_RUNTIME:基于运行时的 CRC8 计算;CRC_8_TABLE:基于表的 CRC8 计算(默认选择) | | **Crc8H2FMode** (ECUC_Crc_00031) | 开关以选择可用的 CRC 8 位(2Fh 多项式)计算方法之一 | CRC_8H2F_HARDWARE、CRC_8H2F_RUNTIME、CRC_8H2F_TABLE(默认) | | **Crc16Mode** (ECUC_Crc_00025) | 开关以选择可用的 CRC 16 位(CCITT)计算方法之一 | CRC_16_HARDWARE、CRC_16_RUNTIME、CRC_16_TABLE(默认) | | **Crc16ARCMode** (ECUC_Crc_00035) | 开关以选择可用的 CRC-16/ARC(多项式 8005)计算方法之一 | CRC_16_ARC_HARDWARE、CRC_16_ARC_RUNTIME、CRC_16_ARC_TABLE(默认) | | **Crc32Mode** (ECUC_Crc_00026) | 开关以选择可用的 CRC 32 位(IEEE-802.3 CRC32 以太网标准)计算方法之一 | CRC_32_HARDWARE、CRC_32_RUNTIME、CRC_32_TABLE(默认) | | **Crc32P4Mode** (ECUC_Crc_00032) | 开关以选择可用的 CRC 32 位 E2E Profile 4 计算方法之一 | CRC_32P4_HARDWARE、CRC_32P4_RUNTIME、CRC_32P4_TABLE(默认) | | **Crc64Mode** (ECUC_Crc_00034) | 开关以选择可用的 CRC 64 位计算方法之一 | CRC_64_HARDWARE、CRC_64_RUNTIME、CRC_64_TABLE(默认) | 所有参数: - Multiplicity:0..1 - Type:EcucEnumerationParamDef - Post-Build Variant Multiplicity:false - Post-Build Variant Value:false - Multiplicity Configuration Class:Pre-compile time(X All Variants) - Value Configuration Class:Pre-compile time(X All Variants) - Scope / Dependency:scope: local ### 10.3 发布信息 [SWS_Crc_00050] ⌈ [3] 中 SRS_BSW_00402 要求的标准化通用发布参数应在本模块的头文件中发布,并需要在 BSW Module Description 中提供。相应的模块缩写可在 [1] 基本软件模块列表中找到。 ⌋() 其他模块特定的发布参数(如果适用)将在下面列出。 | SWS Item | [SWS_Crc_00048] | | |---------|-----------------|---| | **信息元素** | **类型/范围** | **信息元素描述** | | CRC_VENDOR_ID | #define / uint16 | 根据 AUTOSAR 供应商列表的此模块的专用实施的供应商 ID | | CRC_MODULE_ID | #define / uint16 | 来自模块列表的此模块的模块 ID | | CRC_AR_RELEASE_MAJOR_VERSION | #define / uint8 | 适当实施所基于的 AUTOSAR 版本的 major 版本号 | | CRC_AR_RELEASE_MINOR_VERSION | #define / uint8 | 适当实施所基于的 AUTOSAR 版本的 minor 版本号 | | CRC_AR_RELEASE_REVISION_VERSION | #define / uint8 | 适当实施所基于的 AUTOSAR 版本的补丁级别版本号 | | CRC_SW_MAJOR_VERSION | #define / uint8 | 模块的供应商特定实施的 major 版本号。编号是供应商特定的。 | | CRC_SW_MINOR_VERSION | #define / uint8 | 模块的供应商特定实施的 minor 版本号。编号是供应商特定的。 | | CRC_SW_PATCH_VERSION | #define / uint8 | 模块的供应商特定实施的补丁级别版本号。编号是供应商特定的。 | ## 11 不适用的需求 [SWS_Crc_00051] ⌈ 这些需求不适用于本规范。 ⌋(SRS_BSW_00344, SRS_BSW_00404, SRS_BSW_00405, SRS_BSW_00170, SRS_BSW_00412, SRS_BSW_00383, SRS_BSW_00384, SRS_BSW_00388, SRS_BSW_00389, SRS_BSW_00395, SRS_BSW_00398, SRS_BSW_00399, SRS_BSW_00400, SRS_BSW_00401, SRS_BSW_00375, SRS_BSW_00101, SRS_BSW_00416, SRS_BSW_00406, SRS_BSW_00168, SRS_BSW_00423, SRS_BSW_00424, SRS_BSW_00425, SRS_BSW_00427, SRS_BSW_00428, SRS_BSW_00429, SRS_BSW_00432, SRS_BSW_00433, SRS_BSW_00336, SRS_BSW_00337, SRS_BSW_00369, SRS_BSW_00339, SRS_BSW_00422, SRS_BSW_00417, SRS_BSW_00323, SRS_BSW_00409, SRS_BSW_00385, SRS_BSW_00386, SRS_BSW_00161, SRS_BSW_00162, SRS_BSW_00005, SRS_BSW_00415, SRS_BSW_00164, SRS_BSW_00325, SRS_BSW_00342, SRS_BSW_00343, SRS_BSW_00160, SRS_BSW_00007, SRS_BSW_00347, SRS_BSW_00305, SRS_BSW_00307, SRS_BSW_00373, SRS_BSW_00327, SRS_BSW_00335, SRS_BSW_00350, SRS_BSW_00410, SRS_BSW_00314, SRS_BSW_00348, SRS_BSW_00353, SRS_BSW_00361, SRS_BSW_00302, SRS_BSW_00328, SRS_BSW_00312, SRS_BSW_00006, SRS_BSW_00304, SRS_BSW_00378, SRS_BSW_00306, SRS_BSW_00308, SRS_BSW_00309, SRS_BSW_00371, SRS_BSW_00358, SRS_BSW_00414, SRS_BSW_00359, SRS_BSW_00360, SRS_BSW_00330, SRS_BSW_00331, SRS_BSW_00009, SRS_BSW_00172, SRS_BSW_00010, SRS_BSW_00333, SRS_BSW_00321, SRS_BSW_00341, SRS_BSW_00334) --- ## 翻译说明 1. 本文档为 AUTOSAR CP Release 4.4.0 的 CRC 库软件规范(SWS)。 2. 所有 API 标识符(如 `Crc_CalculateCRC8`、`Crc_CalculateCRC8H2F`、`Crc_CalculateCRC16`、`Crc_CalculateCRC16ARC`、`Crc_CalculateCRC32`、`Crc_CalculateCRC32P4`、`Crc_CalculateCRC64`、`Crc_GetVersionInfo`)保留英文原名。 3. 数据类型(`uint8`、`uint16`、`uint32`、`uint64`、`boolean`)保留英文原名。 4. 需求 ID(如 `SWS_Crc_00030`)保留原样。 5. 章节中包含的所有 C 代码片段按原文翻译并保留格式。 6. AUTOSAR 方框符 `⌈⌋` 已保留。 7. 文档涵盖 6 个 CRC 例程:`Crc_CalculateCRC8`(SAE-J1850)、`Crc_CalculateCRC8H2F`(0x2F)、`Crc_CalculateCRC16`(CCITT-FALSE)、`Crc_CalculateCRC16ARC`(0x8005)、`Crc_CalculateCRC32`(IEEE-802.3)、`Crc_CalculateCRC32P4`(0xF4ACFB13)、`Crc_CalculateCRC64`(ECMA)。 8. 第 7.1 节包含详细的 CRC 数学描述、欧几里得算法及其变体的说明。