printf support for 64-bit types on ESP32?

Hi,

is it possible to replace the ESP32 printf with one that supports 64-bit types?

cpu/esp32/ld/esp32.rom.nanofmt.ld says

Address table for printf/scanf family of functions in ESP32 ROM. These functions are compiled with newlib "nano" format option. As such, they don's support 64-bit integer formats.

which is obviously not great.

Thanks, Lars

Hi,

you can use print_u64_dec() [1] instead, which is provided by the module fmt (USEMODULE += fmt).

The lack of 64 bit support is deliberate and consistent with other platforms, as full stdio compatibility is quite expensive in terms of ROM and RAM consumption.

I'd personally happily trade in the newlib implementation for the avrlibc implementation, which in contrast to the newlibs nano stdio stack is truly is optimized for RAM and ROM consumption. And the existence and popularity of picolibc shows, that I'm not the only one with that opinion [2]:

1. Replaced stdio. In place of the large and memory-intensive stdio stack found in newlib, picolibc's stdio is derived from avrlibc's code. [...]

Kind regards, Marian

[1]: http://api.riot-os.org/group__sys__fmt.html [2]: https://keithp.com/blogs/picolibc/

Hi,

you can use print_u64_dec() [1] instead, which is provided by the module fmt (USEMODULE += fmt).

thanks for the pointer! But the fmt module doesn't seem to have a printf/vprintf-style interface with format strings? (The logging functionality that I am trying to get to run is built around that.)

The lack of 64 bit support is deliberate and consistent with other platforms, as full stdio compatibility is quite expensive in terms of ROM and RAM consumption.

Understood. And I wouldn't really care if the ESP32 didn't crash when its printf encounters a 64-bit format string...

Thanks, Lars

Hi Lars,

newlib-nano was introduced for ESP32 with PR #13812. As Marian said, thanks for the detailed explanation, it is consistent with other platforms. See also the comment [1] in this PR.

Regards Gunar

[1]: https://github.com/RIOT-OS/RIOT/pull/13812#issuecomment-613332028

Hi Lars,

The lack of 64 bit support is deliberate and consistent with other platforms, as full stdio compatibility is quite expensive in terms of ROM and RAM consumption.

Understood. And I wouldn't really care if the ESP32 didn't crash when its printf encounters a 64-bit format string...

I can't reproduce it. When I use

  printf("... %" PRIu64 " ... " PRIi64 " ... \n", var)

I just get `... lu ... li ... ` as output.

Do you have an example when it crashes so that I might have a look?

Thanks Gunar

Hi,

maybe providing a (pseudo-)module with an advanced `printf()` version would be a solution? That way people actually needing full support can have it, without the ROM / RAM cost being paid by everyone. However, I'm not sure if one can pick the non-nano stdio from newlib while everything else remains "nano" flavor. (E.g. the non-nano malloc implementation can cause issues when working with non-contiguous memory regions, so just switching to the non-nano newlib via a pseudo module might be more involved.)

One could of course provide a fully distinct `printf()` implementation (e.g. based on the avrlibc) as module in source and use some linker magic to link calls to `printf()` to the custom implementation. I think it would be possible to provide `printf()` with both %llu / %lld support and lower RAM / ROM consumption compared to newlib's implementation. I bet nobody would complain about extra printf() features, if they end up coming with a lower RAM/ROM consumption; so this might end up becoming the default option for newlib based platforms.

While I like the idea of this, I sadly don't have the time to PR this; at least not now. But maybe someone else wants to do so?

Kind regards, Marian