stm32halstm32f7

STM32F745 - HAL_FLASH_Program not writing to flash permanently


I am using HAL_FLASH_Program() to program an uuid into a specific address. I can verify that it writes successfully by reading from the same address. However, if I power cycle the MCU, the memory at that address returns to the original value. If I write to it directly through ST-Link then it stays permanently.

Does anyone know why is that? Do I need to erase the memory location before write to it using HAL_FLASH_Program()? I am using STM32F745.

My code is really simple:

#define UUID_ADDR      (0x080FFFFB)
uint16_t uuid 0x1234
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, UUID_ADDR, uuid);

Thank you


Solution

  • Flash memory requires that the sector you want to write to must be in the erase state before you can write to it.

    For that, you need some extra steps before you can make your write persistent.

    Below is an example in how to do it, but make sure that the addresses match your purpose, here is just a generic code:

    HAL_StatusTypeDef write_halfword_to_flash(uint32_t sector, uint32_t addr, void *data) {
        HAL_StatusTypeDef status = HAL_FLASH_Unlock();
        uint32_t error = 0;
    
        // make sure that this structure matches the datasheet of your chip
        FLASH_EraseInitTypedef FLASH_EraseInitStruct = {
            .TypeErase = FLASH_TYPEERASE_SECTORS,
            .Sector = sector,
            .NbSectors = 1,
            .VoltageRange = FLASH_VOLTAGE_RANGE_3
        };
    
        // clear all flags before you write it to flash
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR |
                    FLASH_FLAG_WRPERR | FLASH_FLAGH_PGAERR | FLAG_PGSERR);
    
        if (status != HAL_OK)
            return status;
    
        // perform the erase first
        HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &error);
    
        if (error)
            return -1;
    
        // now that the sector is erased, we can write to it
        status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr, data);
        if (status != HAL_OK)
            return status;
    
        HAL_FLASH_Unlock();
    
        return status;
    }