Teensy 3.1 Serial.print(F(" "));

Status
Not open for further replies.

aiw

Member
On the usb serial for Teensy 3.1, does it still utilize the print(F(" ")) notation to free up the memory after the print action completes? I had a fairly lengthy code that printed quite a few Strings where I utilized this type of code. After about 40 minutes the code would hang up.

My alternate approach, since most of the Strings were repeats was to create char arrays for them as global variables and just use Serial.print(char array). It seems to be working just fine now.

Old approach:
Serial.println(F("Data Update Requested......"));

New approach:
char dUpdate[] = "Data Update Requested......";

Serial.println(dUpdate);

I want to make sure I'm using the proper approach as I have read that there may be differences in the USB serial and hardware serial and how Serial.print() might work on each.
 
Last edited:
On Teensy 3.1, string constants and all "const" variables automatically go into flash memory, without consuming RAM.

32 bit ARM uses a single 4 Gbyte memory space for everything. There's no separate memory spaces for code and data, like 8 bit AVR.

The PROGMEM and F() and pgm_read_byte() macros do nothing on Teensy 3.1. You can use them, so code written for AVR is compatible, but they're unnecessary.

The one caveat is "const", not "PROGMEM", that determines if an array or variable goes only into flash memory. Some older versions of the AVR compiler did not require "const" to be used together with PROGMEM. Newer AVR tools require const. If you compile older code that has only PROGMEM but not "const" in the definition of an array, it'll be placed in RAM. Just add "const" to make it go into flash, and to also be compatible with the new AVR tools.
 
Thanks for the feedback Paul. I'm not using PROGMEM at all right now, but will add const to the variables to make sure they get loaded into flash

Any clue as to why one would cause a hang up and not the other? I say this on the PJRC site but did not know if it related to Teensy 3.1 or just the older Atmel based Teensy devices...
Large Programs Mysteriously Crash

By default, the compiler places string constants in RAM. If you have have many, RAM can run out quickly. In Arduino, you can use F() to cause strings used with print() to avoid using RAM.
void loop() {
Keyboard.print(F("This is long string does not use RAM, due to F()");
Serial.println(F("Another string"));
delay(250);
}
In C language, usually PSTR() is used, and special functions which access flash memory must be called. Often they have a "_P" suffix.

Large data tables or arrays can also cause trouble. If data is constant, PROGMEM and pgm_read_byte() can be used. See the avr-libc manual for details.
 
Any clue as to why one would cause a hang up and not the other?

Perhaps a bug elsewhere in the code is overwriting memory, and allocating a different number of variables in RAM causes something more critical (likely to cause a crash if overwritten) to be at the location being improperly written?
 
I've found that sprintf_P(char *, PSTR("format string"), ...)
works fine on the AVR but on the T3 the output is absent (truncated or some such).
I remember finding/fixing this once, but it reverted due to a later update of Teensyduino.

I also found that sprintf_P(char *, F("format string"), ...) doesn't work the T3.

So I just #ifdef'd so that on the T3, sprintf() is used rather than the _P version.
Not sure how to declare the format string so it'll be flash-only on the T3. Apparently it's to be done with other than F()

Indeed, few use these, but I used it in a table driven menu system.
 
By default, the string literal for the format string should be const, and should go in the flash memory on ARM processors.
 
By default, the string literal for the format string should be const, and should go in the flash memory on ARM processors.

FWIW, I use the Serial.print(F("....xxxx....")); approach for debugging print statements and the like in my libraries since they can be used by either an AVR or a ARM processor. The ARM processor ignores the extra chatter and the AVR benefits from less SRAM usage, as I understand it.
 
FWIW, I use the Serial.print(F("....xxxx....")); approach for debugging print statements and the like in my libraries since they can be used by either an AVR or a ARM processor. The ARM processor ignores the extra chatter and the AVR benefits from less SRAM usage, as I understand it.
yes, Serial.printf() works on both AVR and T3. But not sprintf_P() as I mentioned above. I use sprintf_P() instead of printf() so I can easily direct the text string to UARTS and other interfaces.
I too use this for statuses in debugging, when SWD isn't available or prudent.
 
Status
Not open for further replies.
Back
Top