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]: 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