Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

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

  1. #1
    Junior Member
    Join Date
    Jan 2014
    Posts
    6

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

    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 by aiw; 01-05-2015 at 02:27 PM.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,516
    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.

  3. #3
    Junior Member
    Join Date
    Jan 2014
    Posts
    6
    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.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,516
    Quote Originally Posted by aiw View Post
    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?

  5. #5
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    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.

  6. #6
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,837
    By default, the string literal for the format string should be const, and should go in the flash memory on ARM processors.

  7. #7
    Senior Member Constantin's Avatar
    Join Date
    Nov 2012
    Location
    In the yard with a 17' Dia. Ferris Wheel
    Posts
    1,408
    Quote Originally Posted by MichaelMeissner View Post
    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.

  8. #8
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Quote Originally Posted by Constantin View Post
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •