crc.h
源文件路径:
common/crc.h所属模块:common(通用工具库) 代码行数:23
1. 文件职责
本文件是 common/crc.c 的对外接口头文件,声明 EMS 固件中全部 5 个通用校验(CRC)函数原型。这些函数被数据层(配置/故障日志/网络事件日志/断电续传存储的落盘校验)、中间件层(逆变器、电表、BMS、AFCI、EVC、并机 CAN 通信帧校验)以及网络层(net/ems.c、net/server.c、net/ems_download.c、net/upd_download.c)广泛调用,是「凡是帧/记录需要校验和」时的统一入口。文件本身不含实现、不含状态、不参与数据流计算,只在编译期把算法签名暴露给包含者。它同时承担「把 chip.h 的基础类型引入到调用方」的副作用(见第 6 节)。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
__CRC_H__ | 宏 | include guard |
GetCrcCode_8_MAXIM | 函数原型 | u8 GetCrcCode_8_MAXIM(u8 *ptr, u32 len),CRC-8/MAXIM |
GetCrcCode_Modbus | 函数原型 | u16 GetCrcCode_Modbus(u8 *pData, u32 wLen),初值 0xFFFF 的反射 CRC-16 |
GetCrcCode_IBM | 函数原型 | u16 GetCrcCode_IBM(u8 *pData, u32 wLen),初值 0x0000 的反射 CRC-16 |
get_data_crc_check | 函数原型 | u16 get_data_crc_check(u16 crc, const u8 data),单字节增量更新 |
GetCrcCode_CRC16 | 函数原型 | u16 GetCrcCode_CRC16(u16 initCRC16, u8 *updata, u32 len),可指定初值的反射 CRC-16 |
本文件不定义结构体、枚举、联合体、位域,也没有除 include guard 外的宏常量。类型 u8 / u16 / u32 来自第 13 行 #include "chip.h"。
3. 函数清单
| 函数名 | 作用域 | 说明 |
|---|---|---|
GetCrcCode_8_MAXIM | 全局(原型声明) | 8 位 Dallas/Maxim CRC,定义于 crc.c:126 |
GetCrcCode_Modbus | 全局(原型声明) | 初值 0xFFFF 的反射 CRC-16,定义于 crc.c:144 |
GetCrcCode_IBM | 全局(原型声明) | 初值 0x0000 的反射 CRC-16,定义于 crc.c:165 |
get_data_crc_check | 全局(原型声明) | 以外部传入的中间值继续计算单字节 CRC,定义于 crc.c:190 |
GetCrcCode_CRC16 | 全局(原型声明) | 可指定初值的反射 CRC-16,定义于 crc.c:212 |
共 5 个原型声明,全部对应 crc.c 中的全局定义;本头文件没有 static 函数、没有函数指针、没有回调类型。
4. 核心逻辑解析
本文件是纯声明文件,不含可执行逻辑。要点集中在接口契约与算法选用上:
4.1 五个接口的算法定位
| 接口 | 多项式/位序 | 初值 | 终值异或 | 等价标准算法 | 工程内用途 |
|---|---|---|---|---|---|
GetCrcCode_8_MAXIM | 0x31(反射 0x8C) | 0x00 | 无 | CRC-8/MAXIM(Dallas 1-Wire) | 并机 CAN 帧第 8 字节 |
GetCrcCode_Modbus | 0xA001(反射) | 0xFFFF | 无 | CRC-16/MODBUS | Modbus RTU 帧尾、落盘记录尾 |
GetCrcCode_IBM | 0xA001(反射) | 0x0000 | 无 | CRC-16/ARC | EVC 升级帧 |
get_data_crc_check | 0xA001(反射) | 由调用方给出 | 无 | CRC-16/MODBUS 的单字节迭代步 | BMS CAN 升级流式累加 |
GetCrcCode_CRC16 | 0xA001(反射) | 参数指定 | 无 | 广义 CRC-16/IBM 族 | BMS 电池日志 |
(上表结论已用 GetCrcCode_CRC16 的标准测试向量核对,详见 crc.c.md 第 4 节。)
4.2 调用约定
- 所有接口都是无状态纯函数:不读写任何全局变量,只按指针和长度计算,可在任意任务上下文重入(
crc.c中的 4 张表都是const只读数据)。 - 长度参数语义统一为「参与计算的字节数」。工程内的调用惯例是:发送侧先按
N字节算 CRC,再把结果小端附加在两字节尾部;接收侧用总长-2计算后与帧尾比对(如midware/afci/afci_comm.c:63、midware/afci/afci_comm.c:155、data/resume_data/flash/flash_data_store.c:201)。 get_data_crc_check是唯一的「非一次性」接口:调用方先自行赋初值(工程内用0xFFFF,见midware/bms/alpha/battery_upgrade.c:607),再逐字节连续调用即可得到与GetCrcCode_Modbus相同的结果。
4.3 通信协议 / 定时 / uCOS-II 配合
无。本文件不涉及帧格式、超时重试、定时调度,不声明信号量或消息邮箱,也不直接引用 uCOS-II API。
5. 对外接口
导出(供外部使用):
| 名称 | 使用方 |
|---|---|
GetCrcCode_Modbus | 覆盖 data / hmi / midware / net 四层的 28 个 .c 文件,是使用面最广的接口 |
GetCrcCode_8_MAXIM | midware/inverter/parallel_comm/parallel_can.c:92、:152、:527、:542(parallel_sci.c:78 处为注释掉的旧调用) |
GetCrcCode_IBM | midware/evc/evc_upgrade.c:61、:68、:134、:143 |
get_data_crc_check | midware/bms/alpha/battery_upgrade.c:287~:290、:395 |
GetCrcCode_CRC16 | midware/bms/alpha/battery_comm.c:1992 |
被调用(本文件引用的外部符号):
| 名称 | 来源 |
|---|---|
chip.h | system/sys/chip.h(第 13 行 include),提供 u8 / u16 / u32 |
本文件不导出任何全局变量。
6. 依赖关系
依赖:
system/sys/chip.h——唯一直接 include;- 间接依赖
UCOSII/uCOS-CONFIG/includes.h(chip.h的调用方普遍会先 include 它)。
被依赖(include 本头文件的文件,按层归类):
- data:
data/fault_warn_log/fault_warn_log.c、data/net_event_log/net_event_log.c、data/resume_data/flash/flash_data_store.c、data/system_config/system_config.c - hmi:
hmi/ui/ui_history_error_log.c - midware:
midware/afci/afci_comm.c、midware/afci/afci_upgrade.c、midware/bms/alpha/battery_comm.c、midware/bms/alpha/battery_upgrade.c、midware/ethernt/ethernet.c、midware/evc/evc.c、midware/evc/evc_ii.c、midware/evc/evc_upgrade.c、midware/interface/modbus/modbus.c、midware/inverter/alphaess/alphaess_comm_usart.c、midware/inverter/alphaess/alphaess_upgrade.c、midware/inverter/ginlong/ginlong_comm_usart.c、midware/inverter/goodwe/goodwe_comm.c、midware/inverter/inovance/inovance_comm_can.c、midware/inverter/inovance/inovance_comm_usart.c、midware/inverter/inovance/inovance_upgrade.c、midware/inverter/parallel.c、midware/inverter/parallel_comm/parallel_can.c、midware/inverter/parallel_comm/parallel_sci.c、midware/inverter/pvcharger.c、midware/inverter/set/set_comm_usart_s5.c、midware/meter/backupbox.c、midware/meter/diesel_generator.c、midware/meter/meter.c、midware/meter/meter_upgrade.c - net:
net/ems.c、net/ems_download.c、net/server.c、net/upd_download.c
合计 35 个包含点(含 common/crc.c 自身),是 common/ 里被引用面最广的头文件之一。
7. 备注与风险点
- 头文件注释与内容不符:第 2 行
@file :crc.h正确,但对应的crc.c文件头写的是@file :convert.c(复制粘贴遗留),容易误导维护者。 chip.h的硬依赖未做条件保护:u8/u16/u32并非本文件定义,一旦包含顺序变化或在无chip.h的环境(如 PC 侧单元测试)编译会整体失败。属正常写法但耦合较紧。- 函数命名不一致:5 个接口里 4 个是
GetCrcCode_*,1 个是get_data_crc_check(小写 + 下划线),且GetCrcCode_8_MAXIM会让人误以为参数是 8 位长度。命名未统一,检索时容易漏掉get_data_crc_check。 - 参数命名暗示了错误的语义:
GetCrcCode_Modbus(u8 *pData, u32 wLen)里的wLen使用了匈牙利前缀w(word/16 位),但实际类型是u32的字节数;GetCrcCode_CRC16(u16 initCRC16, u8 *updata, ...)的updata是拼写错误。 - 无任何参数校验契约:所有原型都没有约定「指针为 NULL 或长度为 0 时的行为」,实现里也没有防护(见
crc.c.md备注 4)。