使stm32上的CRC与软件实现匹配

Make CRC on stm32 match with software implementation

更新。工作代码见post结尾

我已经气死了。如何使 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))