cancel
Showing results for 
Search instead for 
Did you mean: 

Checksum Discrepancy Between STM32CubeProgrammer and ST-LINK Utility: How to Ensure Consistency?

Ivan404
Associate

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.

Case 1: C_2.0.5.hex

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.

Case 2: C_2.4.0.hex

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).

Root Cause Analysis

  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).

  2. 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?

 

2 REPLIES 2
Ivan404
Associate

In addition to this, I am trying to compare this checksum with the one from the memory, and the results are as follows:

STM32CubeProgrammer:

File checksum:
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:

File checksum:
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!

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) ?