STM32,存储在闪存中的变量无法在其他文件中更新
问题描述:
我使用STM32F411RE。 因为我的RAM中没有更多内存。我决定在我的闪存中存储大量变量。为此,我在section.ld
中创建了一个部分。STM32,存储在闪存中的变量无法在其他文件中更新
.large_buffer: ALIGN(4)
{
. = ALIGN(4) ;
*(.large_buffer.large_buffer.*)
. = ALIGN(4) ;
} >FLASH
在main.c
文件,我声明变量如下:
uint8_t buffer[60 * 200] __attribute__ ((section(".large_buffer"), used));
此时一切都OK,缓冲未在RAM(BSS)放养,我可以访问它,重写它。
buffer[25] = 42;
printf("%d\n", buffer[25]); // 42
问题来了,当我想从其他文件编辑变量。
main.c
uint8_t buffer[60 * 200] __attribute__ ((section(".large_buffer"), used));
int main()
{
myFunc(buffer);
}
other.c
myFunc(uint8_t* buffer)
{
buffer[25] = 42;
printf("%d\n", buffer[25]); // 0
}
buffer
在另一个文件(如参数传递)永远不会改变。
我错过了什么吗?
答
由于闪存的物理设计,无法以与写入RAM相同的方式写入闪存。确切地说,你需要擦除扇区/页面(比如〜1-4kB,它在你的MCU数据表中有详细说明)。原因在于,即使闪存没有通电,它们也会保留状态,只要您想要从值0 - > 1中更改任何位,就需要擦除整个扇区(擦除所有位后将设置为1) 。
所以你不能使用Flash作为数据存储器,你可以做的就是使用Flash作为存储常量(只读)值的变量,因此任何查找表都可以完美地适用于那里(通常是编译器,当你stat变量为const将它们放入flash中)。如何写入闪存可以参阅MCU参考手册。
感谢您的回答。在闪存中存储缓冲区(经常需要R/W)是一个很好的解决方案吗? – Epitouille
我不会推荐这个作为可行的解决方案,首先是您需要保存RAM才能够先读取然后写入闪存。写入/擦除比读取慢得多,并且与RAM写入/擦除闪存相比更长。另外,你可以做多少次擦除周期是有限制的,通常约为100k周期。 – koper89
是的,我明白这个问题。在这一点上,我卡住了,因为我无法保存ram。什么可能是一个解决方案?什么优化是相关的? – Epitouille