根据您的编译器,您有一些选择:
- 您可以声明一个指向该结构的指针并初始化该指针
到该地区。
- 告诉编译器变量应该驻留在哪里
指向闪存的指针
声明结构的指针。
将指针分配给 Flash 中的正确地址。
通过取消引用指针来访问变量。
该指针应该被声明和分配为指向常量数据的常量指针。
告诉编译器变量的地址。
某些编译器允许您将变量放置在特定的内存区域中。第一步是在链接器命令文件中创建一个区域。下一步是告诉编译器该变量位于该区域中。
同样,该变量应声明为“static const”。 “静态”是因为只有 1 个实例。 “const”是因为闪存在大多数情况下是只读的。
闪存:易失性与常量
在大多数情况下,闪存无论如何编程,都是只读的。事实上,读取闪存中数据的唯一方法就是锁定它,即使其只读。一般情况下,未经程序一致同意,不会更改。
大多数闪存都是由软件编程的。通常,这是您的程序。如果您的程序要重新编程闪存,它就会知道值已更改。这类似于写入 RAM。这program改变的是价值,而不是硬件。因此Flash是not易挥发的。
我的经验是,Flash 可以通过其他方式进行编程,通常是在程序未运行时。在这种情况下,它仍然不是易失性的,因为您的程序没有运行。 Flash 仍然是只读的。
当且仅当您的执行线程处于活动状态时另一个任务或执行线程对闪存进行编程时,闪存才会是易失性的。我仍然不认为这个案子是volatile。这将是同步性的一个例子——如果 flash 被修改,那么应该通知一些监听器。
Summary
闪存最好被视为只读存储器。尽管某些编译器和链接器允许您在特定的硬编码地址声明变量,但通过指针访问驻留在 Flash 中的变量以获得最佳可移植性。变量应声明为const static
以便编译器可以发出代码来直接访问变量,而不是在堆栈上复制。如果闪存由另一个任务或执行线程编程,则这是同步问题,而不是以下问题之一:volatile。在极少数情况下,在执行程序时,闪存会由外部源进行编程。
您的程序应该提供校验和或其他方法来确定自上次检查以来内容是否已更改。
不要让编译器从闪存初始化变量。
这并不是真正的便携。更好的方法是让初始化代码从闪存加载变量。让编译器从不同的段加载变量需要对编译器和链接器的内部进行大量工作;不仅仅是初始化指向闪存中地址的指针。