Search code examples
embeddedstm32

is stm32 erasing flash even it not writen?


I'm using HAL_FLASHEx_Erase on stm32f103c8.

According to datasheet, Flash memory endurance is just 10k cycles.

my data is 16 bytes so i thought method how to use flash memory like little block with counter

before i notice it erase 1 page each time.

if i erase 1 page that having 16 bytes data at front

is all other bytes in page become lose there endurance cycle even it not written?

this is method what i thought

it use next frame when it lost there endurance

frame = data(16bytes) + counter(2bytes)

page (1k bytes each) data
1 frame_pointer
2 frame1, frame2, frame3 ...
3 frame56, frame57, frame58 ...

Solution

  • Indeed, the entire page needs to be erased if an existing value needs to be changed such your frame pointer. The only exception is if the value has still the initial value after erase, which is hexadecimal FF FF FF FF...

    So the typical approach is to only append data until the page is full and to use the initial FF FF values to detect whether a slot has been used. In your case, it could look like so (note: I don't understand what the counter is for):

    #define TAG_UNUSED 0xffff
    #define TAG_USED 0x1111
    
    typedef struct {
       uint16_t tag;
       uint16_t counter;
       uint8_t data[16];
    } flash_slot;
    
    #define FLASH_PAGE_SIZE 1024
    #define NUM_FLASH_SLOTS (FLASH_PAGE_SIZE/sizeof(flash_slot))
    #define FLASH_SLOTS ((volatile flash_slot*)0x800FC00)
    
    void save_data(uint8_t* data) {
        // find next free slot
        int index;
        for (index = 0; index < NUM_FLASH_SLOTS; index++) {
            if (FLASH_SLOTS[index].tag == TAG_UNUSED)
                break;
        }
    
        if (index == NUM_FLASH_SLOTS) {
           // all slots are used; erase page
           flash_erase_page(FLASH_SLOTS);
           index = 0;
        }
    
        // prepare data to be written
        flash_slot slot;
        slot.tag = TAG_USED;
        slot.counter = 0;
        memcpy(slot.data, data, 16);
    
        // write slot without erasing page (as it's still at FF FF)
        flash_write_data(&FLASH_SLOTS[index], &slot, sizeof(slot));
    }