cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H753 Flash CRC specification

NPato
Associate II

Hi,

The CRC function of the flash module in the STM32H753 is documented as using the polynomial 0x04c11DB7. If I use this module to calculate a CRC over 128 bytes all set to zero I get a non-zero answer (0x11e66c62) so it must also be using an initial value (crc burst size set to 4 = 128 bytes). So what is this initial value? It doesn't appear to be 0xFFFFFFFF as using that in PC code that uses the same polynomial does not produce the same value.

The CRC function in the flash module is largely pointless if it's calculation cannot be reproduced off-chip. Is there example C code anywhere that can reproduce the CRC that the flash modules CRC produces?

Thanks

Nigel

5 REPLIES 5

https://community.st.com/s/question/0D53W000009hqLCSAY so I can find it later

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
NPato
Associate II

Thanks, looks like you've been having fun with STM CRC functions for a while. I'll post if I discover a resolution but it's possible I'll just end up using a software based CRC, will have to bench mark to see how much slower it is.

NPato
Associate II

Hi,

Looks like the STM is reading data as 32bit and then processing the bytes in high to low order which effectively reverses the bytes in each 32bits on a little endian system.

Byte stream of: 0x00 0x11 0x22 0x33 0x44 0x55 0x66 0x77

Read by STM as: 0x33221100 0x77665544

Processed high to low resulting in: 0x33 0x22 0x11 0x00 0x77 0x66 0x55 0x44

It also appears to have a CRC initialisation value of 0xb6c0ae5a.

I have a case open with ST containing this information, so hopefully get some response from ST.

Cheers

Nigel

stabler
Associate

Nigel,

Thanks for your insights into this, I've been banging my head against this all day so I registered to pass along my findings-

It appears that the algorithm applies the initialization value 0xb6c0ae5a to each chunk (chunk size given in CRC_BURST). So with the smallest chunk size (128 bytes), I'm able to calculate the CRC of the entire erased block using the following python code:

# Thanks to Noctis on https://stackoverflow.com/questions/33152005/convert-this-crc32-algorithm-to-python-3-3 for CRC algorithm
CRC_TABLE = (0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
             0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
             0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
             0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD)
 
def dword(value):
    return value & 0xFFFFFFFF
 
def crc32_fast(crc, data):
    crc, data = dword(crc), dword(data)
    crc ^= data
    for _ in range(8):
        crc = dword(crc << 4) ^ CRC_TABLE[crc >> 28]
    return crc
 
def crc32_fast_bytes(crc, bytes_data, byteorder='big'):
    if len(bytes_data) & 3:
        raise ValueError('bytes_data length must be multiple of four')
    for index in range(0, len(bytes_data), 4):
        data = int.from_bytes(bytes_data[index:index+4], byteorder)
        crc = crc32_fast(crc, data)
    return crc
 
 
# Compute CRC
truth = 0xf0317346       # Value computed on STM32H753
data = b'\xff' * 0x80      # 128 byte chunk of erased flash
 
crc = 0
for _ in range(0, 8 * 1024):   # Full 1Mb range
    crc = crc32_fast_bytes(crc ^ 0xb6c0ae5a, data, 'little')
    
print(hex(crc))
print(hex(truth))
 

I haven't fully tested this yet (either with non-uniform data or different chunk sizes), but if I discover anything more I will try to remember to post it here!

Edit: this works with non-uniform data, I have not tested with different chunk sizes.