1
votes

I want to write the contents of a struct to flash memory in my C program for STM32F4 Discovery board using HAL libraries. This is my struct:

typedef struct
{
    RTC_TimeTypeDef time;
    RTC_DateTypeDef date;
    float Data;
} DataLogTypeDef;

I have the option to write Byte, Half-Word, Word and Double-Word to each memory address at a time using the stm32f4xx_hal_flash.c library function:

HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);

My struct contains various data types but I'm not sure how to write the contents using only Byte, Half-Word, Word and Double-Word commands at a time?

2
You should be able to write it using any one of those methods as long as you write out at least sizeof(DataLogTypeDef) bytes of information, and you read it back into a struct in the same way you wrote it and on the same platform (to avoid portability issues). In other words, treat it as a simple block of data.lurker
Thanks for the reply. I am not sure how to arrange the data in order for it to be transferred to memory. I am sure it will take several write operations but how do I instruct the program to perform several write operations each with different parts of the overall struct?b7031719
You don't have to arrange it. If your data is declared as DataLogTypeDef my_data; then you would write a block of memory to flash from address &my_data and that block would be sizeof(DataLogTypeDef) bytes long. Read it back the same way on the same platform and you should be fine.lurker
Thanks for replying. I can kind of follow what you are describing but I am not sure how to code this. Do you have any examples of how to do this kind of write operation? Thanks againb7031719
I'm not sure what the arguments in your flash programming function mean, but suppose you had a function write_flash(from_address, to_address, number_of_bytes) you would just call, write_flash(&my_data, flash_address, sizeof(DataLogTypeDef)).lurker

2 Answers

2
votes

What you have is a flash writing function that will write a byte, word, or double word.

If you want to write your structure to flash the simplest way is to view it as a buffer of bytes or words as long as you read it back the same way on the same platform (and with the same C compiler and compile options). Why the same platform? Because different computer platforms can have a different byte ordering for multi-byte values. Why the same compiler and compiler options? Because a different compiler or different options might pack the data in a struct differently.

So with that in mind, and keeping in mind there's a lot of details you haven't provided regarding how your flash writer should be called, your code might look like this to copy the structure to flash:

DataLogTypeDef my_data;

...

int i;
uint8_t *data_p = &my_data;
flash_address = //put first flash address here

for ( i = 0; i < sizeof(DataLogTypeDef); i++, data_p++, flash_address++ )
    HAL_FLASH_Program(type_byte, flash_address, *data_p);

I don't know what the values are for the first two arguments, so I just put type_byte and flash_address. I'm also assuming flash address is an integer form and is a byte address.

If you want to read the structure back, it might look something like this:

// Initialize i, data_p, and flash_address first

for ( i = 0; i < sizeof(DataLogTypeDef); i++, data_p++, flash_address++ )
    *data_p = Flash_read(flash_address);
0
votes

Unfortunately flash lib stm32f4xx_hal_flash.c only can write:

  • half word (two bytes)
  • word
  • double word

And can not write record byte for byte.

I write two methods for read and write struct:

void ReadRecord(SensorData *pSD, uint32_t flash_address)
{
    uint32_t *ptr = (uint32_t* )pSD;

  for (int i = 0; i < sizeof(SensorData); i+=4, ptr++, flash_address+=4 )   
     *ptr = FlashRead(flash_address);
}

void WriteRecord(SensorData *pSD, uint32_t address)
{
    int i;
    uint32_t *pRecord = (uint32_t* )pSD;  
    uint32_t flash_address = address;

    HAL_FLASH_Unlock();
    for(i=0; i<sizeof(SensorData); i+=4, pRecord++, flash_address+=4)
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_address,*pRecord);
    HAL_FLASH_Lock();       
}

They was check in debugger. Type int read and write good, but float read back with little error in last one or two digit after coma.