【问题标题】:Read/Write Struct to Flash Memory读/写结构到闪存
【发布时间】:2019-06-06 13:39:22
【问题描述】:

我想使用 HAL 库在我的 STM32F4 Discovery 板的 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);

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

【问题讨论】:

  • 只要你写出至少sizeof(DataLogTypeDef)字节的信息,你应该能够使用其中任何一种方法来编写它,并且你用你写的同样的方式把它读回到一个结构中它和在同一个平台上(以避免可移植性问题)。换句话说,将其视为一个简单的数据块。
  • 感谢您的回复。我不确定如何安排数据以便将其传输到内存。我确信这将需要几个写操作,但是我如何指示程序执行几个写操作,每个写操作都有整个结构的不同部分?
  • 你不必安排它。如果您的数据被声明为DataLogTypeDef my_data;,那么您将从地址&my_data 向闪存写入一块内存,该块的长度为sizeof(DataLogTypeDef) 字节。在同一个平台上以同样的方式读回它应该没问题。
  • 感谢您的回复。我可以按照您的描述进行操作,但我不确定如何编写代码。你有任何关于如何进行这种写操作的例子吗?再次感谢
  • 我不确定您的闪存编程函数中的参数是什么意思,但假设您有一个函数write_flash(from_address, to_address, number_of_bytes),您只需调用write_flash(&my_data, flash_address, sizeof(DataLogTypeDef))

标签: struct stm32 stm32f4discovery flash-memory stm32f4


【解决方案1】:

你有一个闪存写入函数,可以写入一个字节、字或双字。

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

因此,考虑到这一点,并牢记您没有提供有关如何调用 Flash 编写器的许多细节,您的代码可能看起来像这样以将结构复制到 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);

【讨论】:

    【解决方案2】:

    可惜flash libstm32f4xx_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 后的最后一位或两位数几乎没有错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-26
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      相关资源
      最近更新 更多