cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446 Calculating Flash CRC in Safety App

gokhannsahin
Associate II

Hi everyone,

I'm developing a safety project and using the STM32F446. To ensure the safety standard, before starting the main code, I need to compare the current flash CRC with the CRC which calculated with SREC. The same structure is being used in another project that has an F3 MCU and it can pass this checking correctly but the F446 can't pass. I see it correctly calculating when it runs step by step so the algorithm is correct and was double-checked. However, something goes wrong when the CRC of all flash is being calculated. What is the problem? 

By the way, I'm using the default CRC settings for F3, not changing any parameter.

Also, I'm developing the project according on XCube Class B.

10 REPLIES 10

>>What is the problem?

Who knows, you show no detail, example data, nor code.

The basic answer is you're doing something wrong, because the CRC is sensitive to data stream, length etc.

.HEX files can be sparse and out-of-order. A better way would be to use a binary image where there is no ambiguity, and perhaps write the CRC at the end so the CRC across the whole image gives a zero residual/remainder if correct.

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

Are you sure SREC is using the same value for unitialized memory areas as the FLASH actually contains (usually 0xFF for erased Flash)? Are you sure SREC is calculating the CRC over the same address range as the F446? Are you using the same SREC config and commands for the F3 and F4 projects?

Try feeding canned (pre-determined) blocks of data to both the F3 and F4 implementations and see if you can find instances where they differ. These can be blocks as short as 16, 32 or 64 bytes to make single-stepping more tolerable if needed.

gokhannsahin
Associate II

The flash data is caused this problem so it ,isn't related to CRC. I guess that it's an variable align problem. Altough the bytes from 0x1C8 to 0x1D0 in the bin files are zero, the Atollic fills these memory as 0xFFFFFFFF, so the CRC calculates wrong. Well, why the Atollic fill these memory as 0xFFFFFFFF? The following images show this problem.

The binfile:

0690X000006C7PyQAK.jpg

Atollic Memory:0690X000006C7Q3QAK.jpg

Bob S
Principal

Probably because those bytes are skipped (not used) in the program memory map. Whatever is generating your binary file is filling unused bytes with zeros, whereas Atollic is looking at the actual FLASH memory which is 0xff when erased (and it has to erase flash before it loads your program). The ELF file (or whatever Atollic is using to program the CPU) likely doesn't have data for those 12 bytes. Look in you MAP file and see if there is a gap. This usually happens when the linker is aligning different memory sections to 16-byte address boundaries.

The fix is to tell whatever program you use to generate the binary file to fill unused spaces with 0xff. Or generate a hex file (Intel Hex, whatever) and use THAT as the input to srec, and tell srec to fill unused memory with 0xff. The hex file will skip unused memory segments. Binary files do not.

gokhannsahin
Associate II

I have tried the following commands but it fills the unused memory as 0x00 again.

SET INPUT_BIN=%TARGET_NAME%.bin -binary
SET INPUT_HEX=%TARGET_NAME%.hex -intel
 
%SREC_PATH%\srec_cat.exe ^
	%INPUT_BIN% ^
	-offset 0x08000000 ^
	−fill 0xff −over 0x08000000 %CRC_ADDR% ^
	-o %INPUT_HEX%

Bob S
Principal

If your input fine is BINARY you are already screwed. Binary files contain data for ALL bytes from the starting address through the ending address, including any unused areas. Whatever is generating your binary file has already made the decision to fill usused bytes with zeros.

You have two options:

(1) If your build procedure does not already generate a hex file, change it so that it does. Then feed the hex file as the input source for srec. Beware the resulting name clash with your output file. I usually name the srec output file something like "%TARGET_NAME%_CRC.hex" so show that it is the version that contains the CRC value.

or (2) Change your build procedure so that whatever creates the binary file fills unused memory with 0xff. Note that I don't know if this is possible. The hex file option is probably the easier choice.

gokhannsahin
Associate II

Thank you @Bob S​ 

Well, I set the output hex as Intel and it generated a hex file. Then the srec calculates the CRC value according to the generated this hex file. However, the data at this hex file will be not the same as the data at MCU memory. As a result, it will calculate wrong, am I wrong?

Bob S
Principal

One experiment is worth a thousand questions. Try it and find out.

There are many variables here that I don't know. How does the CRC calculation in the safety software know the address range over which to calculate the CRC? What file are you using to program the executable image into Flash? Is the "safety" program part of the startup code in the executable, or is it a separate piece of code like a boot loader?

I think I was making an assumption about how your system works. Where does the "safety check" get the CRC value that it compares with the CRC of the flash image? I had presumed that the CRC value was stored at the end of the flash image. Is the output of srec only the CRC value? Or is it the entire image along with the CRC value?

If srec only outputs the CRC value and you somehow pass that to your safety check software separately from the executable image, then they *should* match *if* you use the hex file (or ELF file) to program the executable image into Flash. Because srec fills unused memory with 0xff, and the flash programming steps will skip unused bytes and leave them in their "erased" state which is 0xff.

If srec outputs the executable image along with the CRC (perhaps appended to the last 4 bytes of the image), then yes it will match.

You need to make sure srec uses the same address range to calculate the CRC as your safety software.

Worse case, use srec to also generate a hex or binary image of your executable, filling in 0xff as you do when calculating the CRC. Then use your debugger to dump the memory contents to a binary of hex file. Compare the two and see where they differ. If the hex files have a different number of data bytes per line, use srec AGAIN to read in the hex file and output a new hex file with the same number of data bytes per line.

Bob S
Principal

Oops, that should be "One experiment is worth a thousand GUESSES".