What does the F() do exactly?

Do you really need to store data in FLASH? Doing so isn't "free." You will pay a performance penalty in terms of the time it takes to read from FLASH as well as the complexity in terms of the code necessary to access FLASH.

mkwired:

kb3dow:
Serial << F("This is a test string");

Try

Serial.print( F("This is a test string") );

or

Serial.println( F("This is a test string") );

On my copy of the Arduino 1.0 IDE this code:

#include <Streaming.h>

void setup ()
{
  Serial << F("This is a test string");
  Serial.println( F("This is a test string") );
}
void loop () {}

Gives no errors:

Binary sketch size: 1716 bytes (of a 32256 byte maximum)

Works on both OS/X and Windows XP versions.

Nick, he's not using the same compiler.

mkwired:
Do you really need to store data in FLASH? Doing so isn't "free." You will pay a performance penalty in terms of the time it takes to read from FLASH as well as the complexity in terms of the code necessary to access FLASH.

It's not that bad. In terms of time, the processor can read flash memory quickly. After all, it is getting instructions from it at the rate of a byte every clock cycle. Compare:

Flash "strcpy":

000000be <strcpy_P>:
  be:	fb 01       	movw	r30, r22
  c0:	dc 01       	movw	r26, r24
  c2:	05 90       	lpm	r0, Z+
  c4:	0d 92       	st	X+, r0
  c6:	00 20       	and	r0, r0
  c8:	e1 f7       	brne	.-8      	; 0xc2 <strcpy_P+0x4>
  ca:	08 95       	ret

To normal "strcpy":

000000cc <strcpy>:
  cc:	fb 01       	movw	r30, r22
  ce:	dc 01       	movw	r26, r24
  d0:	01 90       	ld	r0, Z+
  d2:	0d 92       	st	X+, r0
  d4:	00 20       	and	r0, r0
  d6:	e1 f7       	brne	.-8      	; 0xd0 <strcpy+0x4>
  d8:	08 95       	ret

The only difference is changing "ld" to "lpm". The LPM instruction takes 3 clock cycles compared to 2 for LD. So, you lose one clock cycle (62.5 nS) per byte copied.

Nick, How did you reveal that assembler code?

Get verbose output from the compiler (check box in Preferences under Arduino 1.0).

About the second last line will be a .elf file. Copy its entire filename.

Go to a command / console window and type:

avr-objdump -S whatever.elf > foo.txt

The output file (foo.txt) will have the disassembly in it.

excellent, thanks

Hi everybody,

I'm trying to copy a string from the flash memory to a char[] variable. But because of the __FlashStringHelper * type I don't know how to do it.

Any idea?

I'm working on a Web Server with a table which I have to construct on each iteration (see code below). But I don't want to send the string and numerical information separately because of the TCP overhead. So instead, I would like to store and concatenate the info in a fixed size buffer and when full, send it.

I already posted a thread about it (without flash memory) http://arduino.cc/forum/index.php/topic,103110.0.html and I have good performance for a buffer of 60 bytes. But because I'm running out of memory I need to store the HTML code in the flash memory.

I'm having error because of the different types. I need a way to copy the flash values to RAM values.

Tnx!!

const int Buffer_length = 90;
char buffer[Buffer_length];
int TempTable[5][5];

void SecondTable(EthernetClient client)
{
 for (int i = 1; i < 5; i++) {
  int i=1;
  printI(i,client);
  printC(F("</td><td align='center'><input type='text' name='Block"),client);
  printI(i,client);
  printC(F("1' value='"),client);
  printI(TempTable[i-1][0],client);
  printC(F("' size='2' maxlength='2'/>: <input type='text' name='Block"),client);
  printI(i,client);
  printC(F("2' value='"),client);
  printI(TempTable[i-1][1],client);
  printC(F("' size='2' maxlength='2'/></td><td align='center'><input type='text' name='Block"),client);
  printI(i,client);
  printC(F("3' value='"),client);
  printI(TempTable[i-1][2],client);
  printC(F("' size='2' maxlength='2'/>: <input type='text' name='Block"),client);
  printI(i,client);
  printC(F("4' value='"),client);
  printI(TempTable[i-1][3],client);
  printC(F("' size='2' maxlength='2'/></td><td align='center'><input type='text' name='Block"),client);
  printI(i,client);
  printC(F("5' value='"),client);
  printI(TempTable[i-1][4],client);
  printC(F("' size='2' maxlength='2'/></td></tr>"),client);
  }

void printI(int num, EthernetClient client){
  if (strlen(buffer)<Buffer_length-6)      //we add the int value only if we have enough space!
  {
    sprintf(buffer,"%s%d",buffer,num); //we add the int value to the buffer
  }
  else {
    client.println(buffer); //we send the buffer though the net
    buffer[0]='\0'; //we reset the buffer
    sprintf(buffer,"%s%d",buffer,num);
  }
}
void printC(const __FlashStringHelper * info, EthernetClient client){
  int length_array1=strlen(buffer);
  int length_array2=strlen(info);
  if (Buffer_length-1>length_array1+length_array2) 
  {
    strcat(buffer,info); 
  } 
  else {
    client.println(buffer); 
    buffer[0]='\0';
    strcat(buffer,info);
  }
}
strcat_P( buffer, (PGM_P)(info) );

...may work. Otherwise, you will have to use static_cast...

strcat_P( buffer, static_cast<PGM_P>(info) );

nicocarv,

I suggest you learn the way to do PROGMEM way instead of F(). F() doesn't optimize duplicate strings. If you do PROGMEM, you only define the string once and use it any time you want. I'll write some tutorial on my blog and remember to post back here.

mromani:
This thread is the best explanation of the F() macro I found so far... Should be made sticky or turned into some official doc page...

do we have to define the F() macro?

No

To conserve RAM, I added the F() parameter to a section of code to verify the actual use of memory changes and the results are hard for me to understand. Exact figures are as follows. 69 Bytes in 7 Strings, all as basic text in Serial.print statements were inclosed in the brackets of the F() "Macro". (I guess you could call it that.) A quick compile showed that the RAM use was decreased by 56 Bytes, but the Flash, or Program memory, was increased by 194 Bytes. I am assuming this must have something to do with optimization, but really have no idea.
I will try to resolve this by making a very short sketch, with both methods, and compare the resulting machine code, but as I have not really worked with direct machine code for 30 years, my knowledge base is a little outdated. The real problem I am trying to solve is "What is the best way to fit my code into the unit?" Saving RAM was my first concern, as That is used up quicker, but if the compiler is going to use almost 3 times the flash to store the same strings, then the "accounting" task becomes a lot tougher. It should be obvious I am not used to C yet.
So, my real question becomes, are there any options that anyone is aware of in the IDE that controls the methods used for data / string storage and is there a better method of such storage. (As in: Store all strings in a large memory block at the end of the program code and use my own index method as if I were hand coding in assembly?).
I will post back if I find any answers in the inspection of my short sketches. Thanks.

You are over-thinking the situation. The extra Flash is because the Serial.print(const __FlashStringHelper*) method was added to the image.

Constant text strings are always stored in Flash. Using the F-macro prevents them from also consuming SRAM.

Thanks for the Quick Answer. (WOW!)
I'm still a bit confused, however. To keep things simple, I used the same sketch and moved 1 more string of 1 character. Very small, I realize, but this is for me to understand. This did not decrease the RAM use at all. It remained exactly the same. The Flash lost 40 bytes. Does this mean that the compiler is going to add a 39 byte overhead every time I use the F() macro? That seems impossible as the previous increase would have had an additional 273 bytes from just this overhead. The reason I am so picky is that I am using this as a BTR unit, directly interfacing with CNC equipment to replace old tape readers and punches and certain timings are going to be quite critical. As I haven't pulled out the scope yet, and I Have added in lots of code for setting delays, etc., I am not anticipating trouble there, but if just putting in F() adds 39 instructions to the code, that would be something I would want to know. Things will get tight if / when I add an ethernet shield back in and code the unit to accept programs from the network. Currently, I am using Serial2 on a Mega256 as I need 2 full 8 bit wide parallel ports to handle the CNC ports. While the current sketch easily fits, I've already used over 2000 bytes RAM, without any ethernet coding. If I am not going to fit this into the Mega, I won't bother spending the time to code the ethernet protocols.
Just to confuse me more, I added F() to one more string, 11 Bytes long and this time the flash increased by only 12 bytes. I expected this as the extra byte is probably the 0 terminator, as I think that is how C terminates strings. That makes no sense either, as you stated the string constants are already in flash, which they should be. Even as this seems correct, the RAM usage Still did not decrease at all. It's still the exact same number of bytes. I really find it hard to imagine the method is that variable in memory usage, and larger usage for smaller strings. Am I missing something or should I just abort this whole method of looking for timing and fly by the seat of my pants, as it were?

Does this mean that the compiler is going to add a 39 byte overhead every time I use the F() macro?

No.

To keep things simple...

Currently, I am using Serial2 on a Mega256 as I need 2 full 8 bit wide parallel ports to handle the CNC ports. While the current sketch easily fits, I've already used over 2000 bytes RAM, without any ethernet coding.

You have an interesting definition for the word "simple".

I'm still a bit confused, however.

Until you provide source code examples, everyone else is also going to be confused.

Just to confuse me more, I added F() to one more string, 11 Bytes long and this time the flash increased by only 12 bytes. I expected this as the extra byte is probably the 0 terminator, as I think that is how C terminates strings. That makes no sense either, as you stated the string constants are already in flash, which they should be.

You need to post test cases that prove these points. We can't comment on abstract experiments that you claim to have made. There may well be an initial (small) overhead to load in the functions needed to get F() to work, and possibly they may use small amounts of RAM as well. However in the long run, using F() substantially decreases RAM usage.

That makes no sense either, as you stated the string constants are already in flash, which they should be.

They still have the terminator on them in flash. The entire string (in this case 12 bytes) was previously copied to RAM. Again, post your test cases.

Instead of Mucking up this important thread, I will take the situation as it is. I really thank you for the input, as it has helped me to understand how the compiler is operating a little better. I will study this further and learn so that I can ask a proper question, without all the confusion. To remain On-Topic, I accept that I understand the purpose and operation of the F() as well as I am able for my current level of experience.

I will note this current result, for reference. Initially, the sketch was 9562 Bytes code and 2010 bytes of data. Putting every instance of Serial.print (and println) that was a constant string into the brackets of the F() "macro" and adding 1 small subroutine to handle a couple of prints gave weird, but useful, results. The ending size was 10266 Bytes code and 390 bytes of data. This was weird because I compiled each time I did a small section, and the results were never the same. Sometimes the data size didn't change and sometimes it changed drastically. Instead of me making an attempt to examine each coding at the machine level to see why, I just accept it as a fact of the compiler because the end result saved me 1620 Bytes of data area at the cost of 704 bytes of Flash memory. Acceptable trade, in my view, and the results got more predictable as I changed more instances. I realize this shouldn't be the case, but I can only state what happened, not why. I did Not actually ever get to making small sketches as my concern is more for this code than solving compiler methods. I apologize for that. As far as timing, I'll finalize that upon installing the working device and using the scope. I don't think the F() will have much effect, but If it does, I will note it here.

Again, Thanks for the help and if you think anyone might be interested in this code, just tell me where to put it, as it's heavily remarked and quite long. (14 Pages in landscape, 2 column.) The main usage of String constants is the Menu for changing the timings on the fly at the customer location so that I (hopefully) don't need to re-compile there. I doubt anyone needs a full description here, but if there IS interest, let me know. I assume it would go in another thread or database.

I realize this shouldn't be the case, but I can only state what happened, not why.

If it should not be the case, the compiler would not have done what it did.

At least some of the strangeness you are seeing is very likely because of the optimizer. By changing which method is called and which parameters are passed you change what the optimizer can and cannot do for a given section of code. For example, if you have a simple function call at the end of a function the optimizer will use a jump rather than a call. That small difference can easily equate to a dozen bytes of Flash. That's why we need to see concrete examples before we can give you reasons.

Instead of Mucking up this important thread...

Your posts are doing no such thing. The topic at hand is "what does the F() do exactly". That is precisely what you are trying to discuss.

Thanks for the help...

You are welcome.

...if you think anyone might be interested in this code...

I would like to reproduce what you are seeing. Please... Click Reply. Click Attachments and other options. Click Browse. Select the sketch. Click Open. Click Post.