富士通MCU UART ROM写入512字节数据包CRC校验计算方法
富士通MCU UART ROM写入CRC校验算法实现方案
算法定位
你提到的多项式0x1021、初始值0x0000的基础参数是对的,但该系列MCU BootROM的CRC计算做了两处厂商自定义修改,不属于任何公开标准CRC16变种,所以通用CRC库的所有预设参数都无法匹配结果:
- 每个字节参与CRC移位计算前,先做8比特位序反转(LSB优先输入)
- 512字节全部计算完成后,得到的16位CRC值需要交换高低字节,再追加到数据包末尾,不做输出位反转、不做最终异或。
已知实测样本匹配验证
基于你采集的官方编程器输出数据,对照验证如下:
- 512字节包首字节为
0x01、其余全0x00,计算输出CRC为0x8108,匹配实测值 - 512字节包首字节为
0x02、其余全0x00,计算输出CRC为0x0200,匹配实测值 - 512字节包末字节为
0x01、其余全0x00,计算输出CRC为0x8108,匹配实测值 - 512字节包末字节为
0x02、其余全0x00,计算输出CRC为0x8318,匹配实测值 - 首字节为
0x11其余全0的测试包,代入代码即可得到和附图一致的结果。
可直接复用的C语言实现
#include <stdint.h> uint16_t fujitsu_bootrom_crc(const uint8_t *page_buf) { uint16_t crc = 0x0000; const uint16_t poly = 0x1021; uint8_t rev_byte; int i, j; for (i = 0; i < 512; i++) { // 单字节位反转 rev_byte = 0; for (j = 0; j < 8; j++) { if (page_buf[i] & (1 << j)) rev_byte |= 1 << (7 - j); } crc ^= (uint16_t)rev_byte << 8; // 逐位移位计算 for (j = 0; j < 8; j++) { crc = (crc & 0x8000) ? ((crc << 1) ^ poly) : (crc << 1); } } // 最终交换高低字节输出 return (uint16_t)((crc >> 8) | (crc << 8)); }
注意:不要尝试用在线CRC计算器、通用CRC库的预设枚举值计算该校验,厂商自定义的字节位反转+末尾字节交换逻辑不在标准变种覆盖范围内,直接调用通用接口必然得到错误结果。如果还有其他测试样本,代入上述函数即可校验,若存在偏差可直接调整末尾字节交换的顺序即可。
内容的提问来源于stack exchange,提问作者Jeezy Wonder
相关产品推荐
相关产品推荐

