更新。请参阅帖子末尾的工作代码
我已经对此感到生气了。如何使stm32f103上的CRC单元的校验和与软件实现相匹配? Stm 具有多项式
0x04C11DB7
和重置值 0xFFFFFFFF
。所以我尝试用Python计算它。
stm 代码:
uint32_t crc32_hard_block(uint32_t *buf, uint32_t len)
{
CRC_ResetDR();
uint32_t crc = CRC_CalcBlockCRC(buf, len);
return crc;
}
uint32_t buf[4] = {50, 10, 243, 147};
uint32_t crc_hard_block = crc32_hard_block(buf, 4);
Python代码:
custom_crc_table = {}
def int_to_bytes(i):
return [(i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF]
def reverse_int(i, w):
b = '{:0{width}b}'.format(i, width=w)
return int(b[::-1], 2)
def generate_crc32_table(_poly):
global custom_crc_table
for i in range(256):
c = i << 24
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
custom_crc_table[i] = c
def custom_crc32(buf, _poly):
global custom_crc_table
crc = 0xFFFFFFFF
for integer in buf:
b = int_to_bytes(integer)
for byte in b:
top = (crc >> 24) & 0xFF
crc = (crc << 8) | byte
crc = crc ^ custom_crc_table[top]
return crc, reverse_int(crc, 32)
poly = 0x04C11DB7
buf = [50, 10, 243, 147]
generate_crc32_table(poly)
custom_crc, rev = custom_crc32(buf, poly)
print("Custom rev src " + hex(rev))
print("Custom crc " + hex(custom_crc))
对数组 [50, 10, 243, 147] 进行测试给出了输出:
在Python中:
Custom rev src 0x344a9514f010200020100010100020301000203
Custom crc 0x3010002030100020200020100010203ca2a548b #reversed
我的 crc 肯定有问题。
在stm中:
0x491b3bf3
更新
这里是 stm32f103 上软件 crc 的工作代码和 stm32f103 的代码。
Python:
def generate_crc32_table(_poly):
global custom_crc_table
for i in range(256):
c = i << 24
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
custom_crc_table[i] = c & 0xffffffff
def crc32_stm(bytes_arr):
length = len(bytes_arr)
crc = 0xffffffff
k = 0
while length >= 4:
v = ((bytes_arr[k] << 24) & 0xFF000000) | ((bytes_arr[k+1] << 16) & 0xFF0000) | \
((bytes_arr[k+2] << 8) & 0xFF00) | (bytes_arr[k+3] & 0xFF)
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ v)]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 8))]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 16))]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 24))]
k += 4
length -= 4
if length > 0:
v = 0
for i in range(length):
v |= (bytes_arr[k+i] << 24-i*8)
if length == 1:
v &= 0xFF000000
elif length == 2:
v &= 0xFFFF0000
elif length == 3:
v &= 0xFFFFFF00
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v ) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 8) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 16) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 24) )];
return crc
poly = 0x04C11DB7
buf = [50, 10, 243, 147]
generate_crc32_table(poly)
crc_stm = crc32_stm(bytearray(buf))
Stm32f103:
#include <stm32f10x_crc.h>
uint32_t crc32_native(char *bfr, int len, int clear) {
uint32_t crc;
int l = len / 4;
uint32_t *p = (uint32_t*)bfr;
uint32_t x = p[l];
if(clear)
{
CRC_ResetDR();
}
while(l--)
{
crc = CRC_CalcCRC(*p++);
}
switch(len & 3)
{
case 1: crc = CRC_CalcCRC(x & 0x000000FF); break;
case 2: crc = CRC_CalcCRC(x & 0x0000FFFF); break;
case 3: crc = CRC_CalcCRC(x & 0x00FFFFFF); break;
}
return crc;
}
custom_crc_table = {}
def int_to_bytes(i):
return [(i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF]
def generate_crc32_table(_poly):
global custom_crc_table
for i in range(256):
c = i << 24
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
custom_crc_table[i] = c & 0xffffffff
def custom_crc32(buf):
global custom_crc_table
crc = 0xffffffff
for integer in buf:
b = int_to_bytes(integer)
for byte in b:
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[(crc >> 24) ^ byte]
return crc
poly = 0x04C11DB7
buf = [50, 10, 243, 147]
generate_crc32_table(poly)
custom_crc = custom_crc32(buf)
print("Custom crc " + hex(custom_crc))
我尝试了很多方法来获得模仿 HAL STM32f407 实现的 CRC32 python 实现,最后我发现它使用 crc32 mpeg2 算法。对于像我一样陷入困境的人,这里是它的 python 实现。
def crc32mpeg2(buf, crc=0xffffffff):
for val in buf:
crc ^= val << 24
for _ in range(8):
crc = crc << 1 if (crc & 0x80000000) == 0 else (crc << 1) ^ 0x104c11db7
return crc