Go Down

Topic: F() and PROGMEM, flash exhaustion (Read 105 times) previous topic - next topic

arduino39248

The macro F() and the reserved word PROGMEM cause information to be written to the Arduino's flash memory.

What I do not understand is if a program with one or both of those constructs is used in setup(), and the Arduino is powered down, then powered up and run again, etc., does the flash memory get used up or does it somehow purge itself?

If F() and / or PROGMEM are used in the loop() function wouldn't that eat through the flash memory quickly?

In my searching I have not come across anything that mentions how the flash memory is recovered or how it is purged.

guix

#1
Jan 09, 2016, 02:34 am Last Edit: Jan 09, 2016, 02:34 am by guix
Hello and welcome,

The Flash memory is written once, when you upload a sketch, then it can only be read at runtime, and readings does not damage it.

arduino39248

Thanks guix.  If what you said is in any of the documentation, I have missed it.

One more question.  If I use

Serial.print(F("Hello World"));

to write that string to flash memory that one time, how do I access it at run time?  With PROGMEM there is a clear variable associated with the data, but no obviously so with the Serial.print function.

guix

#3
Jan 09, 2016, 03:00 am Last Edit: Jan 09, 2016, 03:19 am by guix
Here is some info about Arduino memories

To use Serial.print with a PROGMEM string, you can cast the variable to __FlashStringHelper*
Code: [Select]
const char string[] PROGMEM = "Hello World";
Serial.println( (__FlashStringHelper*)string );


But only because the print class allow it:
Code: [Select]

size_t Print::print(const __FlashStringHelper *ifsh)
{
  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    if (write(c)) n++;
    else break;
  }
  return n;
}


Other functions, such as strcmp for example, have a PROGMEM version: strcmp_P
Code: [Select]
const char string[] PROGMEM = "Hello World";
...
if ( strcmp_P( "Hello World", string ) == 0 )
...


In some cases you may need to manually read from PROGMEM. See this.


westfw

Quote
If I use Serial.print(F("Hello World"));  to write that string to flash memory
That doesn't "write the string" to flash memory; it causes the string to be created in flash memory (at compile time), and then prints it.  Exactly the same as if it were Serial.print("Hello World"); would create the string in RAM and print it - you create a string in memory, but it has no symbolic name associated with it that would make it a "variable."

On some microcontrollers (notably ARM), using a literal string like "Hello World" would automatically cause the string to be stored in flash memory, but this isn't possible on AVR because flash is a separate "address space" and you need special code to access strings stored there.


Nick Gammon

One more question.  If I use

Serial.print(F("Hello World"));

to write that string to flash memory that one time, how do I access it at run time? 

The string is in flash memory anyway. Where else would it be? The F() macro prevents it being copied into RAM, thus saving RAM.

See: http://gammon.com.au/progmem
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

holmes4

Quote
The macro F() and the reserved word PROGMEM cause information to be written to the Arduino's flash memory.
Wrong! and @westfw not really right

The contents of SRAM is lost when the AVR looses power. So when the processor is restarted it requires that any constants held in SRAM are restored. C/C++ has a default value for all global var's. In addition all global's and all static var which don't use the default need to be setup.

Code is generated for you in order to do this.

Constants such as "This is a STring" are normally created in SRAM (for speed) by copying from EPROM when the processor restarts.

The F() macro tells the compiler to keep the string in eprom and not to create it in SRAM.

Mark

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy