7

我想写一个变量,例如一个数字为 5 的整数到 FLASH 中,然后在电源消失并且设备再次打开后读取它。

我已经知道,为了写东西,我首先需要擦除页面然后再写。

在手册中它说:

  1. 将 OPTKEY1 = 0x0819 2A3B 写入 Flash 选项密钥寄存器 (FLASH_OPTKEYR)
  2. 将 OPTKEY2 = 0x4C5D 6E7F 写入 Flash 选项密钥寄存器 (FLASH_OPTKEYR)

如何执行此任务?

Sector 0 有一个从 0x0800 0000 到 0x0800 3FFF 的块地址,这就是我要写的地方。

这里是手册的链接,第 71 页:STM32 手册

4

2 回答 2

12

您可以使用以下代码通过 HAL 库将数据写入闪存。

void Write_Flash(uint8_t data)
{
     HAL_FLASH_Unlock();
     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
     FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3);
     HAL_FLASH_Program(TYPEPROGRAM_WORD, FlashAddress, data);
     HAL_FLASH_Lock();
}

您应该如下更新链接描述文件。添加并添加. DATA_MEMORY.user_dataSECTIONS

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 320K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 2048K
DATA (rwx)      : ORIGIN = 0x08040000, LENGTH = 128k
}

/* Define output sections */
SECTIONS
{
 .user_data :
  {
    . = ALIGN(4);
     KEEP(*(.user_data))
    . = ALIGN(4);
  } > DATA

您应该在主代码上添加以下属性,以便在上电后读取数据

__attribute__((__section__(".user_data"))) const char userConfig[64];

毕竟这些,你可以通过调用来读取你的闪存数据userConfig[0]

于 2017-06-30T23:02:09.743 回答
3

我正在为 STM32 版本 9.3.0 使用 STM32F407 和 Atollic TrueSTUDIO®。

使用上述建议代码时

属性((部分(".user_data"))) const char userConfig[64];

我的编译器假定userConfig为零。我必须const从声明中删除它才能使其工作。

我的完整解决方案由两部分组成(如上所述,但有一些进一步的修改):

步骤 1 编辑链接器文件:

在记忆中'

FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 896K /* origin size was 1024k, subtracted size of DATA */
DATA (rx)       : ORIGIN = 0x080E0000, LENGTH = 128K

在“部分”中

/* User data section at the end of the flash to store calibration data etc. */
.user_data (NOLOAD):
{
  . = ALIGN(4);
  _user_data_start = .; /* create a global symbol at user_data start */
   KEEP(*(.user_data))
  . = ALIGN(4);
  _user_data_end = .;  /* create a global symbol at user_data end */
} >DATA

第二步写代码:

uint8_t userConfig[64] __attribute__ ((section(".user_data")));
extern uint32_t _user_data_start;
extern uint32_t _user_data_end;
uint8_t ConfArray[16];
uint32_t TestArray[2];

// Copy a part from the userConfig to variable in RAM
for (i = 0; i < 16; i++)
{
    ConfArray[i] = userConfig[i];
}

// get the address of start and end of user_data in flash
// the & is importand, else you would get the value at the address _user_data_start and _user_data_end points to
TestArray[0] = (uint32_t)&_user_data_start;
TestArray[1] = (uint32_t)&_user_data_end;
于 2020-07-30T09:57:59.867 回答