如何在STM32F4,Cortex M4上写入/读取FLASH

时间:2017-06-08 18:59:07

标签: c flash-memory mbed stm stm32f4

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

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

在手册中说:

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

如何执行此任务?

扇区0的块地址从0x0800 0000到0x0800 3FFF,这是我要写的地方。

此处指向手册的链接,第71页:STM32 Manual

2 个答案:

答案 0 :(得分:7)

您可以使用以下代码将数据写入使用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_data中添加SECTIONS

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]来阅读您的Flash数据。

答案 1 :(得分:1)

我使用的是STM32版本9.3.0的STM32F407和AtollicTrueSTUDIO®。

使用上面建议的代码时

属性((( section (“。user_data”))))const char userConfig [64];

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

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

第1步编辑链接器文件:

在“ MEMORY”中

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

第2步编写代码:

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;