13

On the documentation of Arduino, I quote:

http://playground.arduino.cc/Learning/Memory Note: Flash (PROGMEM) memory can only be populated at program burn time. You can’t change > the values in the flash after the program has started running.

And on the PROGMEM description:

http://arduino.cc/en/Reference/PROGMEM Store data in flash (program) memory instead of SRAM. There's a description of the various types of memory available on an Arduino board.

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h. It tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

So can we or can't we? Or it's not the same thing?

2
  • While you can write to (flash) program memory at run time (unless it is locked), the process is a bit more involved, and cannot be accomplished with the PROGMEM directive, which basically just control the allocation process. If you want to see how it can be done, look at the bootloader source. Commented Apr 23, 2014 at 15:22
  • Page write blocks does not make writing to flash impractical. In fact its something looked forward to.
    – AnotherCG
    Commented Oct 7, 2019 at 2:42

1 Answer 1

9

The short answer is no: PROGMEM data is read-only.

Flash memory limitations
The first thing to understand is that Flash memory (where program space lives) is designed for long-term fixed storage. Reading from it is very fast and precise. However, generally speaking, you can't modify it on a byte-by-byte basis (e.g. changing a specific variable). You usually have to erase and re-write it in large blocks. That makes it completely impractical for run-time manipulation, because you'd have to store a lot of redundant information somewhere else while you do the erase and write cycle.

What PROGMEM actually does
Any literal data specified in your code (such as strings and numbers) always reside in program space at first (i.e. in Flash). However, when your sketch actually wants to use that data at runtime, it normally has to allocate some space for it in SRAM and copy it over. That means you end up with two copies: the fixed original in Flash, and the temporary copy in SRAM.

When you use the PROGMEM modifier, you're telling it not to make that second copy in SRAM. Instead, your sketch will simply access the original in Flash. That's very useful if you only ever have to read the data, as it avoids the allocation and copy operations.

However, copying it to SRAM is essential if you want to modify the data. Aside from the Flash limitations I mentioned above, it's also a question of code safety.

If you're able to modify the data stored in program space, then it follows logically that you could also modify the code stored in program space. That would mean that a simple mistake (or in theory a malicious attack) could result in your sketch being partially or fully rewritten at run-time. This could have very unpredictable results, ranging from simply ceasing to work, through to damaging/destroying any connected equipment.

More information
You can learn more about the low-level PROGMEM stuff from here:

An older version of the same PROGMEM tutorial is available here:

1

Not the answer you're looking for? Browse other questions tagged or ask your own question.