Read/Write 闪存结构

Read/Write Struct to Flash Memory

我想使用 HAL 库在 STM32F4 探索板的 C 程序中将结构的内容写入闪存。这是我的结构:

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

我可以选择使用 stm32f4xx_hal_flash.c 库函数一次将字节、半字、字和双字写入每个内存地址:

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

我的结构包含各种数据类型,但我不确定如何一次仅使用字节、半字、字和双字命令写入内容?

您拥有的是一个闪存写入功能,可以写入一个字节、字或双字。

如果您想将结构写入闪存,最简单的方法是将其视为字节或字的缓冲区,只要您在同一平台(并使用相同的 C 编译器和编译选项)。为什么是同一个平台?因为不同的计算机平台可以对多字节值有不同的字节顺序。为什么编译器和编译器选项相同?因为不同的编译器或不同的选项可能会以不同的方式将数据打包到结构中。

考虑到这一点,并记住您没有提供有关应如何调用 flash writer 的很多细节,您的代码可能看起来像这样将结构复制到 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);

我不知道前两个参数的值是多少,所以我只输入 type_byteflash_address。我还假设闪存地址是整数形式并且是字节地址。

如果你想读回结构,它可能看起来像这样:

// 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);

可惜flash lib stm32f4xx_hal_flash.c只能写:

  • 半字(两个字节)
  • 双字

并且不能逐字节写入记录。

我写了两个读写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();       
}

他们正在调试器中检查。类型int 读写良好,但float 读回时在coma 后的最后一两位数字几乎没有错误。