cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to erase flash in NUCLEO-G0B1RE board

jo512
Associate II

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();
}

 

3 REPLIES 3
TDK
Super User

So what happens? What do your log functions output when it fails?

You should set the erase_init.Bank parameter to bank 1.

If you feel a post has answered your question, please click "Accept as Solution".
jo512
Associate II

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=8

 As 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 73

The behavior is as expected.

 

Maybe my linker file also helps

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 144K
  FLASH    (rx)    : ORIGIN = 0x800C200,   LENGTH = (512K - 0xC200)
}