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

memaroo

Member
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);
}
 
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
 
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?
 
@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/5719...sues-with-STL-libraries?highlight=__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]
[COLOR="#FF0000"]works fine.
will not get here 1.[/COLOR]
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
 
@luni - thanks for the link - missed that one. Yeah would be could to include in next update
 
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:

sc.png

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.
 
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.
 
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.
 
Back
Top