STM32G0 Bootloader – Flash Erase Command via FDCAN Doesn't Erase Flash to 0xFF
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-15 9:39 PM - last edited on 2025-06-16 3:14 AM by Andrew Neil
Hello ST Community,
I'm working with the STM32G0B1CCT6 microcontroller and implementing a custom bootloader located at the beginning of flash memory. The bootloader handles firmware updates over FDCAN.
:wrench:Flash Layout:
Bootloader start address: 0x08000000
Application start address: 0x08008000
Total flash: 256 KB
Flash page size: 2 KB
In my bootloader code, I handle a specific FDCAN message with ID 0x555 as a signal to erase the entire application area (from 0x08008000 to 0x080FFFFF).
:white_heavy_check_mark:What works:
The bootloader receives the erase command correctly from FDCAN.
It calls HAL_FLASHEx_Erase() and returns HAL_OK.
The UART debug log confirms the erase was “successful”.
:cross_mark:The problem:
After erasing, when I read back the flash content at address 0x08008000, I still see the previous application data (e.g., 0x20024000, 0x08008859, etc.), not 0xFFFFFFFF as expected.
:magnifying_glass_tilted_left:Debug output example:
? Waiting for FDCAN ERASE command (ID=0x555)...
? ERASE command received!
? Flash Erased.
FLASH[0x08008000] = 0x20024000
FLASH[0x08008004] = 0x08008859
FLASH[0x08008008] = 0x08008845
FLASH[0x0800800C] = 0x08008847
I have already checked the Option Bytes using STM32CubeProgrammer:
:counterclockwise_arrows_button:My Question:
Why does the application flash area not get fully erased (all bytes to 0xFF) even though HAL_FLASHEx_Erase() returns success?
Is there something specific I need to configure for STM32G0B1CCT6 to allow proper flash erasure?
I’ve attached my bootloader code and debug output for reference.
Any help is appreciated. Thank you!
- Labels:
-
Bootloader
-
CAN
-
FDCAN
-
Flash
-
STM32G0 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-16 2:56 AM
Hello @AKG123
At first glance, it seems your application is using the FDCAN2 instance. However, according to AN2606 (Table 102, page 244), only the FDCAN1 instance supports bootloader communication. Could you please try using FDCAN1 to see if it resolves the issue?
With regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-16 3:13 AM
Indeed it does:
/**
* @brief FDCAN2 Initialization Function
* @PAram None
* @retval None
*/
static void MX_FDCAN2_Init(void)
{
/* USER CODE BEGIN FDCAN2_Init 0 */
/* USER CODE END FDCAN2_Init 0 */
/* USER CODE BEGIN FDCAN2_Init 1 */
/* USER CODE END FDCAN2_Init 1 */
hfdcan2.Instance = FDCAN2;
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-17 5:14 AM - last edited on 2025-06-17 5:24 AM by Andrew Neil
Duplicate - merged
Hi all,
I'm working on a custom FDCAN bootloader for STM32G0B1. The bootloader receives firmware in chunks over FDCAN and writes it to flash starting at 0x08008000. The workflow is:
Bootloader receives an ERASE command (CAN ID 0x555).
It calls HAL_FLASHEx_Erase() to erase flash from page 16 (start of app).
After erase, it sets flash_erased = true and writes chunks.
Firmware is uploaded chunk by chunk via FDCAN using HAL_FLASH_Program() (double word).
Problem:
The first time after programming the bootloader via ST-LINK (i.e., blank flash), everything works fine.
But on the second firmware update, when I send the ERASE command:
HAL_FLASHEx_Erase() returns HAL_OK.
But flash content is not actually erased (verified via printf() memory dumps — old data is still present).
As a result, HAL_FLASH_Program() fails with HAL_ERROR and data isn't overwritten.
Even though the erase function "claims" to succeed, memory remains unchanged.
Things I’ve Verified:
WRP (Write Protection) is fully disabled. No RDP or PCROP either.
The correct number of pages is being erased.
I'm dumping flash memory after erase to check content manually.
Still, flash erase sometimes "pretends" to work but doesn’t.
Questions:
Why does HAL_FLASHEx_Erase() return success when flash content is not erased?
Are there known cache/instruction prefetch/flash controller issues on STM32G0 causing this?
What else can I do to reliably erase the flash between firmware updates?
Is there any low-level workaround or manual verification method recommended?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-17 5:25 AM
@AKG123 you still seem to be using FDCAN2 - as @SirineST said, the bootloader is not supported on FDCAN2.
Did you try FDCAN1 ?
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-17 5:35 AM
I khnow but I'm working on a custom FDCAN bootloader for STM32G0B1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-17 6:26 AM
So why didn't you mention that earlier - when @SirineST brought it up?
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2025-06-17 8:54 PM
I have already mentioned in my question see this ---- I'm working with the STM32G0B1CCT6 microcontroller and implementing a custom bootloader located at the beginning of flash memory. The bootloader handles firmware updates over FDCAN.
I'm working on a custom FDCAN bootloader for STM32G0B1. The bootloader receives firmware in chunks over FDCAN and writes it to flash starting at 0x08008000. The workflow is:
