2025-10-15 4:46 AM
Hi
I am using the function below to erase the flash, but am not able to do the same.
I have to erase from address 0x0803E000UL i.e. page 124
The function does basically
1. HAL_FLASH_Unlock
2. HAL_FLASHEx_Erase(&erase_init, &page_error) - where page is 124
3. reads the erased flash area
4. HAL_FLASH_Lock
Am I missing something? I would not prefer to run the function in ram
I have MCUboot running and my application running on slot 0 is based on FreeRTOS. I am trying to erase slot1.
#define SLOT1_BASE_ADDR 0x0803E000UL
void erase_slot1_flash(void)
{
HAL_StatusTypeDef status;
uint32_t page_error = 0;
FLASH_EraseInitTypeDef erase_init;
uint32_t page_index;
/* Determine actual flash size (in KB) from system memory register */
uint32_t flash_size_kb = *(uint16_t *)FLASHSIZE_BASE;
uint32_t flash_start = FLASH_BASE;
uint32_t flash_end_addr = FLASH_BASE + (flash_size_kb * 1024UL) - 1UL;
printf("SLOT1_BASE_ADDR = 0x%08lX\r\n", (unsigned long)SLOT1_BASE_ADDR);
printf("FLASH_BASE = 0x%08lX\r\n", (unsigned long)FLASH_BASE);
printf("FLASH_SIZE_KB = %lu\r\n", (unsigned long)flash_size_kb);
printf("FLASH_START_ADDR = 0x%08lX\r\n", (unsigned long)flash_start);
printf("FLASH_END_ADDR = 0x%08lX\r\n", (unsigned long)flash_end_addr);
/* Sanity check: make sure SLOT1 lies within flash */
if ((SLOT1_BASE_ADDR < flash_start) || (SLOT1_BASE_ADDR > flash_end_addr)) {
printf("Error: SLOT1_BASE_ADDR is outside internal flash range!\r\n");
return;
}
/* Compute which flash page the slot address belongs to */
page_index = (SLOT1_BASE_ADDR - FLASH_BASE) / FLASH_PAGE_SIZE;
HAL_FLASH_Unlock();
printf("Before erase: ");
for (uint8_t i = 0; i < 16; i++) {
uint8_t val = *(uint8_t *)(SLOT1_BASE_ADDR + i);
printf(" %02x", val);
}
printf("\n\r");
/* Prepare erase configuration */
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
erase_init.Page = page_index;
erase_init.NbPages = 1;
printf("Erasing page (index=%lu, address=0x%08lX)\r\n",
(unsigned long)page_index, (unsigned long)SLOT1_BASE_ADDR);
/* Optional: clear prior flash flags */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR |
FLASH_FLAG_RDERR |
FLASH_FLAG_FASTERR |
FLASH_FLAG_MISERR |
FLASH_FLAG_PGSERR |
FLASH_FLAG_WRPERR |
FLASH_FLAG_PROGERR |
FLASH_FLAG_OPERR);
status = HAL_FLASHEx_Erase(&erase_init, &page_error);
if (status != HAL_OK) {
printf("Erase failed! HAL status=%d Flash error=%lu\r\n",
status, HAL_FLASH_GetError());
} else {
printf("Erase successful.\r\n");
}
printf("-After erase: ");
for (uint8_t i = 0; i < 16; i++) {
uint8_t val = *(uint8_t *)(SLOT1_BASE_ADDR + i);
printf(" %02x", val);
}
printf("\n\r");
HAL_FLASH_Lock();
}
Solved! Go to Solution.
2025-10-20 3:03 PM
This works and is more immune to errors and less ambiguous than a series of assignments:
FLASH_EraseInitTypeDef erase_init = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.Banks = FLASH_BANK_1,
.Page = page_index,
.NbPages = 1
};
2025-10-15 6:29 AM
So what happens? What do your log functions output when it fails?
You should set the erase_init.Bank parameter to bank 1.
2025-10-15 6:36 AM
Missed it
I have some more observations
when #define SLOT1_BASE_ADDR 0x0803E000UL is
FLASH_START_ADDR = 0x08000000
FLASH_SIZE_KB = 512
FLASH_END_ADDR = 0x0807FFFF
SLOT1_BASE_ADDR = 0x0803E000
Before erase: 48 65 6c 6c 6f 20 66 72 6f 6d 20 46 72 65 65 52
Erasing page (index=124, address=0x0803E000)
Erase successful.
-After erase: 48 65 6c 6c 6f 20 66 72 6f 6d 20 46 72 65 65 52
Before write: 48 65 6c 6c 6f 20 66 72 6f 6d 20 46 72 65 65 52
Write failed @0x0803e000, err=8As shown above, Line 8 and 9 should be FFs but not
When #define SLOT1_BASE_ADDR 0x08040000UL is
FLASH_START_ADDR = 0x08000000
FLASH_SIZE_KB = 512
FLASH_END_ADDR = 0x0807FFFF
SLOT1_BASE_ADDR = 0x08040000
Before erase: 70 72 61 6a 6f 73 68 20 64 69 64 20 74 68 69 73
Erasing page (index=128, address=0x08040000)
Erase successful.
-After erase: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Before write: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
String written at 0x08040000
-After write: 70 72 61 6a 6f 73 68 20 64 69 64 20 74 68 69 73The behavior is as expected.
2025-10-15 6:39 AM
Maybe my linker file also helps
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K
FLASH (rx) : ORIGIN = 0x800C200, LENGTH = (512K - 0xC200)
}
2025-10-15 7:16 AM
If HAL reports success, it probably erased something.
Did you fix the uninitialized Banks parameter in the code? Note that your pages are in different banks.
2025-10-15 7:21 AM
Hi TDK
Thanks for pointing out, I did not do this, What is this?
Sorry, I am pretty new to ST subsystem as I am migrating from Atmel and NXP to ST
2025-10-15 7:23 AM
But then also why are the other banks working? Can you point me to a quick document please
2025-10-15 8:56 AM
The reference manual explains how the flash banks work and how they're organized.
The HAL source code is the best reference for what needs to be passed to HAL functions. In this case, look at the definition for FLASH_EraseInitTypeDef.
2025-10-15 10:14 AM
Try this in place of the three assignments (lines 38+):
FLASH_EraseInitTypeDef erase_init = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.Page = page_index,
.NbPages = 1
};
2025-10-16 1:27 AM
Hi gbm
How does this help?
FLASH_EraseInitTypeDef erase_init = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.Page = page_index,
.NbPages = 1
};Is there some compiler or linker issue. I just checked my assembler code, both generated the same code
Can you please explain me? Am I missing something in STM ecosystem?
P.S.: I have been advised multiple times by others not to use ST products, as the whole ecosystem and datasheet is a mess. I fear all these are leading me to the same path.