1

我知道我可以通过将数组声明为“const”来强制将数组放入 ARM 中的 FLASH 中。但这并不是真正的 const 数组:我希望能够定期对其进行写入。我有三个大型阵列,占用了我可用的 128kB SRAM 中的约 50k,但我的 FLASH 比我需要的多一个数量级。如何在不声明它们为 const 的情况下将这三个数组强制放入 FLASH 中?使用 IAR,顺便说一句。

尝试使用 __no_init 关键字;根据链接器映射文件,这没有效果。

4

4 回答 4

6

要回答最初的问题,您可以编写一个链接描述文件来强制任何变量驻留在内存的预定区域中(声明它们const不会强制编译器将其放入 FLASH,这只是一个强烈的建议)。

另一方面,过多的 FLASH 本身并不是在闪存中保留非const阵列的好理由。其中原因有:1)根据芯片的不同,对 FLASH 存储器的访问可能比 RAM 访问慢得多(尤其是写入) 2)FLASH 只能重写有限次数:偶尔不会有问题重写,但如果你的代码不断重写闪存,你可以很快毁掉它。3)写入FLASH有特殊的程序(ARM很容易,但还是没有写入RAM那么简单)。

于 2013-09-09T17:39:37.957 回答
3

C 语言、编译器等无法生成芯片/电路板特定的闪存例程。如果您希望使用闪存页面来存储读/写数据,您将必须至少拥有一页内存和一些读/写例程。您需要有很多这些变量来克服将主副本保存在闪存中所需的 ram 成本和执行时间。一般来说,每次将值写入闪存时,都需要读出整个页面,擦除页面,然后在更改了一项的情况下写回整个页面。现在,如果您知道您的闪存是如何工作的(通常是擦除为 1 并写入零),您可以阅读先前的版本,比较差异,如果不需要擦除,则写入该项目。

如果你没有几十个你想这样做的变量,那么不要打扰。你会想要为这个闪存中的每个变量声明一个 const 偏移量并有一个读/写例程

const unsigned int off_items=0x000;
const unsigned int off_dollars=0x004;
...

unsigned int flash_read_nv ( unsigned int offset );
void flash_write_nv ( unsigned int offset, unsigned int data); 

所以这个使用.data的代码:

items++;
dollars=items*5;

使用您将变量保留在闪存中的愿望变为:

unsigned int ra,rb;

ra= flash_read_nv(off_items);
rb= flash_read_nv(off_dollars);
ra++;
rb=ra*5;
flash_write_nv(off_items,ra);
flash_write_nv(off_dollars,ra);

当然,闪存写入需要数百到数千个时钟周期或更长时间才能执行。此外,还需要 64、128 或 256 字节的 ram(或更多),具体取决于闪存页面的大小。

于 2013-09-09T17:51:40.483 回答
2

信不信由你,这个页面是在查看如何使用 AVR ARM 编译器将数据存储在闪存中时弹出的最佳内容。

在手册的第 359 页(编译器的 v7.50 附带的那个)上,确实表明这是将数据放入闪存的一种方式:

#define FLASH _Pragma("location=\"FLASH\"")

但是,在手册的第 332 页上,它说:

“声明为 const 的静态和全局对象在 ROM 中分配。”

我对其进行了测试,似乎 IAR 编译器不需要编译指示,因为指定 const 已经将其放入闪存中(如原始问题中所述)。

从其他答案来看,OP 似乎并不想使用闪存。但是,如果像我这样的人来此页面了解如何使用 AVR ARM 编译器将数据存储在闪存中,我希望我的回答可以为他们节省一些时间。

于 2016-03-11T00:02:15.317 回答
1

在 IAR 中,您可以按如下方式声明您的数组:

__root __no_init const uint8_t myVect[50000] @0x12345678

当然,0x12345678 是 FLASH 中的地址。

于 2018-06-13T15:36:04.350 回答