AnsweredAssumed Answered

STM32L4 HAL_FLASH_Program without erase

Question asked by Br_ggemann.Dieter on Feb 22, 2017
Latest reply on May 5, 2017 by Uwe Bonnes

Hi

 

I need to write a flag (double word) to flash to tell a botloader not to jump to the app but to start a DFU interface.

The bootloader dumps the flash page which contains settings for the app and writes the buffer back to flash with the flag erased.

 

Within the app the flag can only be written if the flash page gets erased first although its location is guaranteed to be erased.

 

Here are the relevant parts:

 

uint32_t write_flash_vars(uint64_t* data, uint16_t length, uint16_t offset)
{
    uint32_t Address = FLASH_USER_START_ADDR;
    __IO uint64_t data64 = 0;

    Address += offset;

    HAL_FLASH_Unlock();

    while (length > 0)
    {
        data64 = *(__IO uint64_t *) data;

        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, data64) == HAL_OK)
        {
            Address += 8;
            data++;
            length--;
        }
        else
        {
            HAL_FLASH_Lock();
            return HAL_FLASH_GetError();
        }
    }
    HAL_FLASH_Lock();
    return HAL_OK;
}

uint32_t erase_flash_page(void)
{
    //Erase flash page(s)
    //Fill EraseInit structure
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Page = FLASH_PAGE;
    EraseInitStruct.Banks = 0;
    EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;

    HAL_FLASH_Unlock();
   
    /* Clear OPTVERR bit set on virgin samples */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);

    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
    {
        // PAGEError will contain the faulty page
        // error code from 'HAL_FLASH_GetError()'
        HAL_FLASH_Lock();
        return HAL_FLASH_GetError();
    }
    else
    {
        HAL_FLASH_Lock();
        return HAL_OK;
    }
}

void start_bootloader(void)
{
    HAL_NVIC_SystemReset();
}

void config_state_switch(const char *cmd)
{
    char buf[20];
    char label[8] = "DFU";

    if (strcmp(cmd, "reboot") == 0)
    {
        start_bootloader();
    }
    else if (strcmp(cmd, "bootloader") == 0)
    {

     //   erase_flash_page();

        write_flash_vars((uint64_t*) label, 1, 1016);

        start_bootloader();
....
}

 

 

If the "erase_flash_page()" is commented out I get the error 0x2a within the program call which is

HAL_FLASH_ERROR_PROG | HAL_FLASH_ERROR_PGA | HAL_FLASH_ERROR_PGS

 

With the "erase_flash_page()" call the thing works as expected.

 

I'm trying to avoid wearing.

How can I achieve the same state as after the erase without actually erasing the page?

 

Dieter

Outcomes