STM32 HAL Tutorial: Ensuring Flash Memory Reliability
Abstract
Learn how to use FLASH ECC and CRC on STM32 to verify the integrity of flash memory data. Step-by-step guide for safe storage of firmware, calibration data, and configuration.
1. Introduction
Embedded systems often rely on FLASH memory to store:
- Firmware
- Configuration parameters
- Calibration tables
Data corruption in flash can occur due to power failures, radiation, or programming errors.
STM32 provides hardware ECC (Error Correction Code) and you can also implement CRC checks to ensure flash integrity.
By the end of this episode, you’ll be able to:
- Understand FLASH ECC and its role in error detection/correction.
- Compute CRC for flash content using HAL.
- Implement flash integrity checks before using stored data.
2. Prerequisites
- STM32 board with flash memory support
- STM32CubeIDE installed
Knowledge of HAL, CRC, and flash programming
3. Understanding FLASH ECC
- ECC automatically detects and corrects single-bit errors in flash.
- Double-bit errors are detected but cannot be corrected.
- ECC is hardware-supported on many STM32 MCUs (including the STM32G0s).
Important: FLASH ECC can’t be disabled, while some STM32 have RAM ECC, which can be enabled, but that is only available on newer STM32 devices. You can check ECC status in the reference manual.
4. Using CRC for Flash Integrity
Even with ECC, you may want to verify all blocks of flash programmed. To do that, we can calculate the CRC as a post build and store the CRC content into a known address. The srec_cat program is used to assemble the given input files into a single output file.
Example on how to use it via post build or command line:
- ..\srec_cat.exe YOUR_PROJECT_NAME.hex -Intel -fill 0xFF 0x08000000 0x080040FC -STM32 0x080040FC -o YOUR_PROJECT_NAME_SRECORD.hex -Intel
Command Breakdown
The command is read from left to right, processing the input file through a series of filters and actions.
- srec_cat.exe This is the executable for the SRecord utility, a tool used to manipulate FLASH load files (like .hex, .s19, .bin). The cat part is short for “concatenate,” as its primary function is to combine and modify these files.
- YOUR_PROJECT_NAME.hex -Intel This is your input file.
- YOUR_PROJECT_NAME.hex: The firmware file generated by your compiler/IDE (e.g., Keil, IAR, GCC).
- -Intel: Specifies that the input file is in the Intel HEX format, which is a standard format for representing machine code.
- -fill 0xFF 0x08000000 0x080040FC This is an action that fills a specified memory range.
- -fill 0xFF: Fills any gaps in the memory range with the hexadecimal value $0xFF$. This is important because the CRC calculation needs to be performed over a contiguous block of memory. Erased flash memory on a microcontroller typically reads as $0xFF$, so this ensures the unused space has a defined value.
- 0x08000000 0x080040FC: This is the memory range to fill. It starts at address $0x08000000$ and ends just before address $0x080040FC$. This range typically corresponds to a portion of the Flash memory on the STM32 device.
- -STM32 0x080040FC This is a special filter for STM32 microcontrollers. It calculates a 32-bit Cyclic Redundancy Check (CRC) value over the entire memory image loaded so far (from $0x08000000$ to $0x080040FC$).
- The calculated CRC value is then inserted into the file at the memory address specified: $0x080040FC$.
- -o YOUR_PROJECT_NAME_SRECORD.hex -Intel This specifies the output file.
- -o: The output flag.
- hex: The name of the new file that will be created.
- -Intel: Specifies that the new file should also be in the Intel HEX format.
5. Verifying Flash Integrity
uint32_t readCrc = HAL_CRC_Accumulate(&hcrc, flashBuffer, FLASH_SIZE_WORDS);
if(readCrc == storedCrc)
{
// Flash data is valid
}
else
{
// Flash corruption detected
Error_Handler();
}
- This method allows you to detect any accidental corruption.
Works for configuration, calibration tables, or firmware blocks.
6. Combining ECC + CRC
- ECC handles single-bit errors automatically at hardware level.
- CRC checks multi-bit integrity at software level.
- Together, they provide high reliability for critical applications:
- Firmware updates
- Industrial controllers
- Data logging systems
7. Hands-On Lab Example
- Define the FLASH size for the CRC calculation.
- Build the Application to check the size to adjust the #define and Post Build Script
..\srec_cat.exe EP14.hex -Intel -fill 0xFF 0x08000000 0x080043FC -STM32 0x080043FC -o EP14_SRECORD.hex -Intel
4. Calculate and store CRC before programming.
5. Adjust the debug settings to program the binary with the CRC
6. Verify CRC with the terminal or by using the [Memory] View during debug session.
Full Source Code: hackerembedded/STM32_EP14
8. Compiling and Running
- Build Project → Click hammer icon.
- Flash Project → Connect STM32 and run (Ctrl + F11).
- Test: Monitor the results via serial terminal
9. Advantages of FLASH ECC + CRC
- Protects critical firmware and configuration from corruption
- Detects multi-bit errors that ECC alone cannot correct
- Provides robustness for industrial and IoT applications
- Easy integration using HAL CRC functions
10. Common Issues & Fixes
| Issue | Cause | Solution |
|---|---|---|
| HAL_CRC_Calculate fails | CRC peripheral not initialized | Ensure HAL_CRC_Init() called via CubeMX code |
| CRC mismatch | Wrong array length or data | Verify FLASH_SIZE_WORDS matches memory block |
| Flash read incorrect | Address misalignment | Use 32-bit aligned addresses |
| ECC not detecting error | ECC not enabled on device | Check reference manual; some MCUs require ECC activation |


