Using PROGMEM data

I was reading the reference about PROGMEM data (PROGMEM - Arduino Reference)
and I've found in internet examples using thing like this:

Serial.println(PSTR("this is a test"));

But I've also found this case:

Serial.println(F("this is a test"));

I'm tried both in one program where has ram problems, and found that the second case works better. My question is what is the difference? In which case should I use each one?

I've also seen some places where they uses P() instead of F()

I've found that there is a very usefull sprintf_P() function that can use PSTR() as parameter but if I use F() instead, the compiler reports an error.

You have a mixture of Arduino and avr gcc code.
The Arduino uses the arv gcc compiler, and every low level function can also be used with the Arduino.

For the Arduino, the 'F()' macro is created:

Serial.println(F("Hello string in flash memory"));

But the 'F()' macro is something typical for the Arduino IDE only.

The sprintf_P() functions are avr gcc functions, they work with PSTR.

sprintf_P( buffer, PSTR("Hello number twelve: %d"), 12);

Perhaps this will be fixed some day. For now it is a little inconsistant.

Krodal:
Perhaps this will be fixed some day. For now it is a little inconsistant.

Ok, I understand.

But I've found stranges different results when I use F() and PSTR() in Serial.println. In a sketch that uses ethercard for tcp/ip (high memory usage), I had problems of garbage sent to Serial instead of some constant strings. I thought that PSTR was stored on flash, then it can't be modified after uploading the program. Then, I suppose PSTR is copying the string to RAM or something like this. This sould not be problem but I received the garbage... Then I replaced PSTR with F and the problem was solved... but F can only be used in Serial.print and a few places, PSTR works with sprintf, strcmp, etc.

PSTR is the same as declaring a string in flash with PROGMEM.
So you can use sprintf_P() and strcpy_P() with PSTR and also with PROGMEM strings.

The Serial.println() uses the 'stream' class. The 'F()' macro is for that class.

anv:
But I've found stranges different results when I use F() and PSTR() in Serial.println. In a sketch that uses ethercard for tcp/ip (high memory usage), I had problems of garbage sent to Serial instead of some constant strings.

You'd need to post your problem sketch.