我想写一个变量,例如一个数字为5的整数到FLASH,然后在电源消失后再次打开设备读取它。
我已经知道为了写东西我首先需要擦除页面然后写。
在手册中说:
- 在Flash选项密钥寄存器(FLASH_OPTKEYR)中写入OPTKEY1 = 0x0819 2A3B
- 在Flash选项密钥寄存器中写入OPTKEY2 = 0x4C5D 6E7F(FLASH_OPTKEYR)
醇>
如何执行此任务?
扇区0的块地址从0x0800 0000到0x0800 3FFF,这是我要写的地方。
此处指向手册的链接,第71页:STM32 Manual
答案 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;