我可以使用PROGMEM写入闪存吗?


11

在Arduino的文档中,我引用:

http://playground.arduino.cc/Learning/Memory 注意:闪存(PROGMEM)存储器只能在程序刻录时填充。程序开始运行后,您将无法更改>闪存中的值。

并在PROGMEM说明中:

http://arduino.cc/en/Reference/PROGMEM将 数据存储在闪存(程序)存储器中,而不是SRAM中。有Arduino板上可用的各种类型的内存的描述。

PROGMEM关键字是一个变量修饰符,仅应与pgmspace.h中定义的数据类型一起使用。它告诉编译器“将该信息放入闪存”,而不是通常存放在SRAM中。

那么我们可以还是不能?还是不一样?


尽管您可以在运行时写入(闪存)程序存储器(除非已被锁定),但该过程要复杂得多,并且不能使用PROGMEM指令来完成,该指令基本上仅控制分配过程。如果要查看如何完成,请查看引导加载程序源。
克里斯·斯特拉顿

页面写块不会使写闪存变得不切实际。实际上,它是值得期待的。
Anothercg Gmail

Answers:


9

简短的答案是“否”:PROGMEM数据是只读的。

闪存的局限性
首先要了解的是,闪存(程序空间所在的位置)是为长期固定存储而设计的。从中读取非常快速且准确。但是,一般来讲,您不能逐字节进行修改(例如,更改特定变量)。通常,您必须大块地擦除并重新写入。这对于运行时操作来说是完全不切实际的,因为在执行擦除和写入周期时,您必须在其他位置存储大量冗余信息。

PROGMEM实际执行的操作
在代码中指定的任何文字数据(例如字符串和数字)始终始终首先位于程序空间中(即Flash中)。但是,当您的草图实际上想在运行时使用该数据时,通常必须在SRAM中为其分配一些空间并进行复制。这意味着您最终得到了两个副本:Flash中的固定原件和SRAM中的临时副本。

使用PROGMEM修饰符时,是在告诉它不要在SRAM中复制第二个副本。取而代之的是,您的草图将仅在Flash中访问原始文件。如果您只需要读取数据,那将非常有用,因为它避免了分配和复制操作。

但是,如果要修改数据,则必须将其复制到SRAM。除了上面提到的Flash限制外,这也是代码安全性的问题。

如果您能够修改存储在程序空间中的数据,那么从逻辑上讲,您还可以修改存储在程序空间中的代码。这意味着一个简单的错误(或理论上是恶意攻击)可能会导致您的草图在运行时被部分或完全重写。从停止运行到损坏或破坏任何连接的设备,这都可能带来非常不可预测的结果。

更多信息
您可以从此处了解有关低级PROGMEM内容的更多信息

此处提供了该PROGMEM教程的较旧版本:


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.