我正在研究 ISO CAN-FD 中的 CRC,但在计算实际校验序列时遇到问题。
首先,我仔细阅读了规范
ISO 11898-1:2015
,它说明了如何进行计算。
然后,我定义了一个框架来尝试计算 CRC:
请注意,红色零是填充位。
相同的帧已添加到 CANalzyer 配置中,我的 CAPL 脚本打印 FrameCRC =
0x6bd
。
我已经使用 Numpy 实现了 ISO 文档中描述的算法,但我的结果与 CANalyzer 返回的结果不匹配。
我的代码如下(它可能不是完美的 numpy-ic 编码,我是这个库的新手):
def crc(data):
gen_poly = np.array([1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1])
crc_reg = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
for bit in data:
crc_next = abs(bit - crc_reg[0])
crc_reg = np.roll(crc_reg, -1) # Shift one position left (1)
crc_reg[-1] = 0 # Shift one position left (2)
if crc_next == 1:
reg_new = abs(crc_reg - gen_poly)
crc_reg = np.copy(reg_new)
return crc_reg.copy()
我还以为我可能误解了文档,
crc_reg
和gen_poly
必须是18位长。所以我这样修改代码:
gen_poly = np.array([1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1])
;crc_reg = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
(共 18 位);但效果并不好。我实在想不通自己到底错在哪里。我已经对所有内容进行了多次审查。
编辑: 按照@Reinderien的建议,我提供输入数据和预期的输出数组:
input_data = np.array([
0, # SOF
1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, # ID
0, # RTR
0, # IDE
1, # EDL
0, # RES
1, # BRS
0, # ESI
1, 0, 0, 0, # DLC
1, 1, 1, 1, 1, 0, 1, 1, 1, # Byte 1
1, 1, 0, 1, 1, 1, 1, 1, 0, 1, # Byte 2
1, 1, 1, 1, 0, 1, 1, 1, 1, # Byte 3
1, 0, 1, 1, 1, 1, 1, 0, 1, 1, # Byte 4
1, 1, 1, 0, 1, 1, 1, 1, 1, 0, # Byte 5
1, 1, 1, 1, 1, 0, 1, 1, 1, # Byte 6
1, 1, 0, 1, 1, 1, 1, 1, 0, 1, # Byte 7
1, 1, 1, 1, 0, 1, 1, 1, 1, # Byte 8
1, 1, 0, 0, # StuffCount + Parity
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 # 17 bits at zero
])
expected_output = np.array([0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1]) # 0x6bd
您不处理 CRC 所在的 17 位零。 (只需删除或注释掉输入中的该行即可。)然后你的 python 代码输出
[0 0 0 0 0 0 1 1 0 1 0 1 1 1 1 0 1]
。