2025-04-09 11:29 AM
Hi everyone.
When validating firmware integrity for an STM32F4 project, different checksum values are observed between:
STM32 ST-LINK Utility (v4.6.0) (deprecated? Or not recommend for new design at least...).
STM32CubeProgrammer (v2.19.0).
This discrepancy correlates with unprogrammed memory regions in the .hex file. Since ST-LINK Utility is no longer maintained, we need a reliable way to align checksum using modern tools like STM32CubeProgrammer.
STM32 ST-LINK Utility Output:
Address Ranges: [0x08000000 - 0x08000194] [0x08004000 - 0x08004004] [0x08008000 - 0x08031674] [0x08031678 - 0x08034448] Checksum: 0x00F5FA57
STM32CubeProgrammer Output:
Segments: [0] Address=0x08000000, Size=0x194, Checksum=0x00003BC2 [1] Address=0x08004000, Size=0x4, Checksum=0x00000000 [2] Address=0x08008000, Size=0x2C448, Checksum=0x00F5C291 Total Checksum: 0x00F5FE53
Key Observations:
4-byte gap excluded by ST-LINK Utility: 0x08031674 to 0x08031678.
Difference: 0x3FC (exactly 0xFF * 4), confirming STM32CubeProgrammer includes gaps filled with 0xFF.
STM32 ST-LINK Utility Output:
Address Ranges: [0x08000000 - 0x08000194] [0x08004000 - 0x08004004] [0x08008000 - 0x080307FC] [0x08030800 - 0x080334F8] Checksum: 0x00F0AABE
STM32CubeProgrammer Output:
Segments: [0] Address=0x08000000, Size=0x194, Checksum=0x00004EF7 [1] Address=0x08004000, Size=0x4, Checksum=0x00000000 [2] Address=0x08008000, Size=0x2B4F8, Checksum=0x00F05FC3 Total Checksum: 0x00F0AEBA
Key Observations:
4-byte gap excluded by ST-LINK Utility:0x080307FCto0x08030800.
Difference: 0x3FC (same pattern as Case 1).
Gaps in the HEX File:
STM32 ST-LINK Utility: Computes checksums only over explicit data, ignoring gaps.
STM32CubeProgrammer: Includes gaps, padding them with 0xFF (erased Flash value).
Linker Script Configuration:
Original script split Flash into fixed regions:
MEMORY { VECTOR (xrw) : ORIGIN = 0x08000000, LENGTH = 16K USER_FLASH (xrw) : ORIGIN = 0x08004000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 224K }
Reserved large blocks (e.g., 16 KB) for small sections like .isr_vector (400 bytes), creating gaps.
Is it possible to configure STM32CubeProgrammer to ignore gaps (as ST-LINK Utility did) or define explicit fill values when working with firmware? I would also like to know if ST provides official documentation on checksum calculation that reconciles old tools with modern ones.
And now that ST-LINK Utility is obsolete, what is ST's recommended workflow for checksum validation in production environments?
2025-04-09 12:47 PM
In addition to this, I am trying to compare this checksum with the one from the memory, and the results are as follows:
STM32CubeProgrammer:
13:32:49 : ====================== File Checksum Calculator =====================
13:32:49 : Segments total number : 3
13:32:49 : Segment [0] :
13:32:49 : Address = 0x08000000
13:32:49 : Size = 0x194
13:32:49 : Checksum = 0x00003BC2
13:32:49 : Segment [1] :
13:32:49 : Address = 0x08004000
13:32:49 : Size = 0x4
13:32:49 : Checksum = 0x00000000
13:32:49 : Segment [2] :
13:32:49 : Address = 0x08008000
13:32:49 : Size = 0x2C448
13:32:49 : Checksum = 0x00F5C291
13:32:49 : Segments total checksum : 0x00F5FE53
13:32:49 : -----------------------------------------------------------------------------------------------
Memory checksum
13:32:52 : Memory [0x08000000 : 0x0802B664] - Checksum : 0x014445D5
STM32 ST - LINK Utility:
13:33:58 : [C_2.0.5.hex] opened successfully.
Address Ranges [0x08000000 0x08000194] [0x08004000 0x08004004] [0x08008000 0x08031674] [0x08031678 0x08034448]
13:33:58 : [C_2.0.5.hex] checksum : 0x00F5FA57
Memory checksum:
13:36:16 : [0x08000000:0x0802B664] Memory Checksum: 0x014445D5
The memory checksum is the same in both programs, but the file checksums are different. Im not sure if theres a way to compare the checksum of the file with the memory checksum to ensure that the code on the STM32 matches the intended version.
Thanks a lot!
2025-04-10 12:28 AM - edited 2025-04-10 12:29 AM
Hmm. The last address should be 0x08008000+0x2C448 = 0x0802B664 ... but CubeProgrammer says 0x0802B664 ? Fishy.
Is the end of the last segment from 0x0802B664 to 0x0802B664 filled with FF or 0 (in memory) ?