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

Thread: Serial.printf, sprintf, std::ostringstream not implemnte for floats on Teensy4.

  1. #1
    Junior Member
    Join Date
    Mar 2019
    Posts
    14

    Serial.printf, sprintf, std::ostringstream not implemnte for floats on Teensy4.

    there are 2 issues in the attached sketch.

    NotImplemented demonstrates that Serial.printf, and sprintf do not support floats on Teensy 4. They do on Teensy 3.6.

    Crash1 demonstrates that ostringstream will crash the Teensy 4 if passed a float. This works on Teensy 3.6

    Code:
    #include <sstream>
    #include <string>
    
    
    void Crash1()
    {
      std::ostringstream s;
      s << 3;
      Serial.println("works fine.");
      
      s << 4.5f;
      Serial.println("will not get here 1.");
    }
    
    
    
    #include <stdio.h> 
    #define MAX_FLOAT 100 
    
    // On teensy 3.6 this was implemented. affects Serial.printf too
    void NotImplemented()
    {
      char buf[MAX_FLOAT]; 
      sprintf(buf, "%d", 3); 
      Serial.println((std::string("Expect something in this box [") + buf + "]").c_str());
      
      sprintf(buf, "%f", 2.5f); 
      Serial.println((std::string("Expect something in this box [") + buf + "]").c_str());
      
      Serial.printf("Expect something in this box [%f]\n", 2.5f);
    }
    
    
    
    void setup() {
      Serial.begin(115200);
      Serial.println("setup()");
    }
    
    void loop() {
      NotImplemented();
      
      //Crash1(); // Teensy 4 will crash hard if you uncomment this.
    
      Serial.println("loop");
      delay(10);
    }

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    935
    Regarding printf and sprintf:

    Running this
    Code:
    void setup()
    {
        while (!Serial) {}
        Serial.println("setup()");
    
        char buf[100];
        sprintf(buf, "Expect something in this box [%f]\n", M_SQRT2);
        Serial.printf("%s", buf);
    
    
        Serial.printf("Expect something in this box [%f]\n", M_PI);
    }
    
    void loop()
    {
    }
    on a T4 prints:
    Code:
    setup()
    Expect something in this box [1.414214]
    Expect something in this box [3.141593]
    for me

  3. #3
    Junior Member
    Join Date
    Mar 2019
    Posts
    14
    It doesn't for me (with your code). I'm using Teensyduino 1.51. You?

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    935
    I used TD1.50 and just tested it with a clone of the current core. Works without problems (as expected). What do you mean by doesn't work? Doesn't compile or doesn't print?

  5. #5
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,325
    @luni and @memaroo

    Just ran the code in post#1 and got the following error on a T4, which we have seen before which is probably being caused by adding sstream:
    Code:
    f:/arduino-1.8.12/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/armv7e-m/fpu/fpv5-d16\libgcc.a(unwind-arm.o): In function `get_eit_entry':
    unwind-arm.c:(.text+0x134): undefined reference to `__exidx_end'
    unwind-arm.c:(.text+0x138): undefined reference to `__exidx_start'
    collect2.exe: error: ld returned 1 exit status
    
    Error compiling for board Teensy 4.0.
    See https://forum.pjrc.com/threads/57192...ht=__exidx_end. Adding
    Code:
    unsigned __exidx_start;
    unsigned __exidx_end;
    after the includes gives as output
    Code:
    setup()
    Expect something in this box [3]
    Expect something in this box [2.500000]
    Expect something in this box [2.500000]
    loop
    Expect something in this box [3]
    Expect something in this box [2.500000]
    Expect something in this box [2.500000]
    loop
    Expect something in this box [3]
    Expect something in this box [2.500000]
    Expect something in this box [2.500000]
    loop …….
    If you add this include to the beginning of your sketch:
    Code:
    #include <iostream>
    The problem with running crash1 works fine:
    Code:
    setup()
    Expect something in this box [3]
    Expect something in this box [2.500000]
    Expect something in this box [2.500000]
    works fine.
    will not get here 1.
    loop
    Expect something in this box [3]
    Expect something in is box [2.500000]
    Expect something in this box [2.500000]
    works fine.
    will not get here 1.
    loop

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    935
    See also https://forum.pjrc.com/threads/59767...l=1#post230936 for the STL issue.

    Regarding your printf issue: Are you sure you have USB Serial enabled in the build options?

  7. #7
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,325
    @luni - thanks for the link - missed that one. Yeah would be could to include in next update

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,081
    Quote Originally Posted by memaroo View Post
    It doesn't for me (with your code). I'm using Teensyduino 1.51. You?
    Maybe you could be more specific about how it doesn't work?

    I tried luni's code from msg #2 with 1.52-beta2, and I get this:

    Click image for larger version. 

Name:	sc.png 
Views:	7 
Size:	21.3 KB 
ID:	19785

    One quick (but unlikely) suggestion - make sure you have not selected "Smallest Code" in Tools > Optimize. That causes the linker to use the "nano" libc specs, which uses a very small printf implementation that omits floating point support to save code size.

  9. #9
    Junior Member
    Join Date
    Mar 2019
    Posts
    14
    Luni said "it prints for me" i said "it doesnt for me."

    I was using "Optimize: Smallest Code." If I use any other settings my normal program wont fit in memory. I have another thread about that. I added FLASHMEM to large functions but the size didnt change by 1 byte (in some cases, in other cases it did reduce). I will continue that issue on the other thread.

    When i switch this example to "Optimize: Fastest", it failed to compile needing these:
    unsigned __exidx_start;
    unsigned __exidx_end;

    After adding those, it does compile and does print. Even "Crash1()" works fine when set to "Not smallest" optimization.

    It sounds like I will need to figure out my program size issue if i want printf and floats. In the mean time i've switched to "dtostrf" for float rendering.

    I get the intention of using reduced features for small code size, but i dont think it should break without warning by just changing optimization level. I've always been afraid of changes in behavior when changing optimization levels.

    Thank you for the fast responses.

  10. #10
    The memory taken by functions in RAM is allocated in 32k blocks so FLASHMEM only makes a difference when you cross a new block border.

Posting Permissions

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