在闪存中为用户数据分配内存(STM32F4 HAL)
Allocating memory in Flash for user data (STM32F4 HAL)
我正在尝试使用 STM32F405 的内部闪存来存储重启后保留的一堆用户可设置字节。
我正在使用:
uint8_t userConfig[64] __attribute__((at(0x0800C000)));
为我要存储的数据分配内存。
当程序启动时,我检查第一个字节是否设置为0x42
,如果没有,我将其设置为:
HAL_FLASH_Unlock();
HAL_FLASH_Program(TYPEPROGRAM_BYTE, &userConfig[0], 0x42);
HAL_FLASH_Lock();
之后,我检查 userConfig[0]
中的值,我看到 0x42
...太棒了!
然而,当我点击重置并再次查看该位置时,它不再是 0x42
...
知道我哪里出错了吗?我也试过:
#pragma location = 0x0800C00
volatile const uint8_t userConfig[64]
但我得到了相同的结果..
好的,感谢 clive1
,我在 the ST forums 上找到了答案。此示例适用于 STM32F405xG。
首先我们需要修改链接脚本文件(.ld文件)中的内存布局
修改现有的FLASH,为DATA增加一行。这里我已经分配了所有 section 11
.
MEMORY
{
FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 1M-128K
DATA (RWX) : ORIGIN = 0x080E0000, LENGTH = 128k
...
...
}
Manual for editing linker files on the sourceware website
在同一个文件中,我们需要添加:
.user_data :
{
. = ALIGN(4);
*(.user_data)
. = ALIGN(4);
} > DATA
这将创建一个名为 .user_data
的 section
,我们可以在程序代码中对其进行寻址。
最后,在您的 .c 文件中添加:
__attribute__((__section__(".user_data"))) const uint8_t userConfig[64]
这指定我们希望将 userConfig
变量存储在 .user_data
部分并且 const
确保 userConfig
的地址保持静态。
现在,要在运行时写入此闪存区域,您可以使用 stm32f4 stdlib 或 HAL 闪存驱动程序。
在你可以写入闪存之前,它必须被擦除(所有字节设置为 0xFF)出于某种原因,HAL 库的指令没有说明这样做...
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_11, VOLTAGE_RANGE_3);
HAL_FLASH_Program(TYPEPROGRAM_WORD, &userConfig[index], someData);
HAL_FLASH_Lock();
我正在尝试使用 STM32F405 的内部闪存来存储重启后保留的一堆用户可设置字节。
我正在使用:
uint8_t userConfig[64] __attribute__((at(0x0800C000)));
为我要存储的数据分配内存。
当程序启动时,我检查第一个字节是否设置为0x42
,如果没有,我将其设置为:
HAL_FLASH_Unlock();
HAL_FLASH_Program(TYPEPROGRAM_BYTE, &userConfig[0], 0x42);
HAL_FLASH_Lock();
之后,我检查 userConfig[0]
中的值,我看到 0x42
...太棒了!
然而,当我点击重置并再次查看该位置时,它不再是 0x42
...
知道我哪里出错了吗?我也试过:
#pragma location = 0x0800C00
volatile const uint8_t userConfig[64]
但我得到了相同的结果..
好的,感谢 clive1
,我在 the ST forums 上找到了答案。此示例适用于 STM32F405xG。
首先我们需要修改链接脚本文件(.ld文件)中的内存布局
修改现有的FLASH,为DATA增加一行。这里我已经分配了所有 section 11
.
MEMORY
{
FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 1M-128K
DATA (RWX) : ORIGIN = 0x080E0000, LENGTH = 128k
...
...
}
Manual for editing linker files on the sourceware website
在同一个文件中,我们需要添加:
.user_data :
{
. = ALIGN(4);
*(.user_data)
. = ALIGN(4);
} > DATA
这将创建一个名为 .user_data
的 section
,我们可以在程序代码中对其进行寻址。
最后,在您的 .c 文件中添加:
__attribute__((__section__(".user_data"))) const uint8_t userConfig[64]
这指定我们希望将 userConfig
变量存储在 .user_data
部分并且 const
确保 userConfig
的地址保持静态。
现在,要在运行时写入此闪存区域,您可以使用 stm32f4 stdlib 或 HAL 闪存驱动程序。
在你可以写入闪存之前,它必须被擦除(所有字节设置为 0xFF)出于某种原因,HAL 库的指令没有说明这样做...
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_11, VOLTAGE_RANGE_3);
HAL_FLASH_Program(TYPEPROGRAM_WORD, &userConfig[index], someData);
HAL_FLASH_Lock();