2020-06-12 09:08 AM
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
2020-06-12 09:49 AM
This question has been asked here before, and never got a satisfactory answer. The mechanics of this are not documented properly.
2020-06-12 10:04 AM
https://community.st.com/s/question/0D53W000009hqLCSAY so I can find it later
2020-06-12 03:10 PM
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.
2020-06-18 06:53 AM
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
2020-08-09 11:50 PM
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.