Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Arduino's "F()" actually do?

Tags:

I have asked a similar question before, but I realize that I can't make heads or tails of the macrology and templateness. I'm a C (rather than C++) programmer.

What does F() actually do? When does it stuff characters into pgmem (flash)? When does it pull characters out of pgmem? Does it cache them? How does it handle low-memory situations?

like image 381
iter Avatar asked May 16 '13 21:05

iter


People also ask

What does F () do Arduino?

If you use F() you can move constant strings to the program memory instead of the ram. This will take up space that will decrease the amount of other code you can write.

What does serial print f ()) do?

printf allows strings to be built by combining a number of values with text. Serial.

What is macro F Arduino?

What the F() macro Does. The F() macro tells the compiler to leave this particular array in PROGMEM. Then when it is time to access it, one byte of the data is copied to RAM at a time.

How does progmem work?

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. PROGMEM is part of the pgmspace.


2 Answers

There are no templates involved, only function overloading. The F() macro does two things:

  • uses PSTR to ensure that the literal string is stored in flash memory (the code space rather than the data space). However, PSTR("some string") cannot be printed because it would receive a simple char * which represents a base address of the string stored in flash. Dereferencing that pointer would access some random characters from the same address in data. Which is why F() also...

  • casts the result of PSTR() to __FlashStringHelper*. Functions such as print and println are overloaded so that, on receiving a __FlashStringHelper* argument, they correctly dereference the characters in the flash memory.

like image 102
user4815162342 Avatar answered Sep 28 '22 08:09

user4815162342


BTW. For the ESP32 library, both of these functions are defined in the following files:

# PSTR :  ../Arduino/hardware/espressif/esp32/cores/esp32/pgmspace.h # F    :  ../Arduino/hardware/espressif/esp32/cores/esp32/WString.h 

And the F(x):

// An abstract class used as a means to provide a unique pointer type // but really has no body class __FlashStringHelper; #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal))) ... 

Also for ESP32, PSTR(x) is not needed and is just x: #define PSTR(s) (s).

like image 36
not2qubit Avatar answered Sep 28 '22 08:09

not2qubit