libc/picolibc: Support 'long long' and 'minimal' printf variants

Picolibc's 'minimal' printf mode reduces functionality and size even more
than the 'integer' mode. Use this where memory is at a premium and where
the application knows that it does not require exact printf semantics.

1.8.5 adds two more printf variants, 'long long' and 'minimal'. The 'long
long' variant is the same as the 'integer' variant but with long long
support enabled. The 'minimal' variant reduces functionality and size even
more than the 'integer' mode. Applications can use this where memory is at
a premium and where the application does not require exact printf
semantics.

With these two added variants, the SDK has enough options so that all of
the cbprintf modes can be supported with the pre-compiled bits:

 1. CBPRINTF_NANO - picolibc's 'minimal' variant
 2. CBPRINTF_REDUCED_INTEGRAL - picolibc's 'integer' variant
 3. CBPRINTF_FULL_INTEGRAL - picolibc's 'long long' variant
 4. CBPRINTF_FB_SUPPORT - picolibc's 'double' variant

This patch makes the cbprintf Kconfig values drive the default picolibc
variant, disables picolibc variants not capable of supporting the required
cbprintf level, but allows applications to select more functionality in
picolibc than cbprintf requires.

Note that this depends on the SDK including picolibc 1.8.5. Without that,
selecting the 'minimal' or 'long long' variant in Zephyr will end up with
the default variant from picolibc, which is the full version with floating
point support. When using the module things will work as specified.

Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Keith Packard 2023-09-12 23:51:33 -07:00 committed by Chris Friedt
parent 5347a834af
commit 7a5fcb8c60
4 changed files with 61 additions and 15 deletions

View file

@ -12,7 +12,6 @@ config REQUIRES_FULL_LIBC
config REQUIRES_FLOAT_PRINTF
bool "Requires floating point support in printf"
select PICOLIBC_IO_FLOAT if PICOLIBC
select CBPRINTF_FP_SUPPORT if MINIMAL_LIBC
select NEWLIB_LIBC_FLOAT_PRINTF if NEWLIB_LIBC
help

View file

@ -17,6 +17,12 @@ if(NOT CONFIG_PICOLIBC_USE_MODULE)
if(CONFIG_PICOLIBC_IO_FLOAT)
zephyr_compile_definitions(PICOLIBC_DOUBLE_PRINTF_SCANF)
zephyr_link_libraries(-DPICOLIBC_DOUBLE_PRINTF_SCANF)
elseif(CONFIG_PICOLIBC_IO_MINIMAL)
zephyr_compile_definitions(PICOLIBC_MINIMAL_PRINTF_SCANF)
zephyr_link_libraries(-DPICOLIBC_MINIMAL_PRINTF_SCANF)
elseif(CONFIG_PICOLIBC_IO_LONG_LONG)
zephyr_compile_definitions(PICOLIBC_LONG_LONG_PRINTF_SCANF)
zephyr_link_libraries(-DPICOLIBC_LONG_LONG_PRINTF_SCANF)
else()
zephyr_compile_definitions(PICOLIBC_INTEGER_PRINTF_SCANF)
zephyr_link_libraries(-DPICOLIBC_INTEGER_PRINTF_SCANF)

View file

@ -31,16 +31,42 @@ config PICOLIBC_HEAP_SIZE
If set to -2, then the value of COMMON_LIBC_MALLOC_ARENA_SIZE
will be used.
config PICOLIBC_IO_LONG_LONG
bool "support for long long in integer-only printf/scanf"
choice PICOLIBC_IO_LEVEL
prompt "Picolibc printf/scanf level"
default PICOLIBC_IO_MINIMAL if CBPRINTF_NANO
default PICOLIBC_IO_LONG_LONG if CBPRINTF_FULL_INTEGRAL
default PICOLIBC_IO_INTEGER
help
Includes support for long long in integer-only printf/scanf. long long
types are always supported in the floating-point versions.
Selects the level of printf and scanf support
config PICOLIBC_IO_FLOAT
bool "support for floating point values in printf/scanf"
bool "full support for integer/floating point values in printf/scanf"
help
Include floating point support in printf/scanf functions.
Include full floating point and integer support in printf/scanf
functions.
config PICOLIBC_IO_LONG_LONG
bool "full support for integer values, including long long, in printf/scanf"
depends on !REQUIRES_FLOAT_PRINTF && (!CBPRINTF_FP_SUPPORT || CBPRINTF_NANO)
help
Includes full integer with long long, but no floating
point in printf/scanf.
config PICOLIBC_IO_INTEGER
bool "full support for integer values, other than long long, in printf/scanf"
depends on !REQUIRES_FLOAT_PRINTF && ((!CBPRINTF_FP_SUPPORT && !CBPRINTF_FULL_INTEGRAL) || CBPRINTF_NANO)
help
Include full integer other than long long, but no floating point
in printf/scanf.
config PICOLIBC_IO_MINIMAL
bool "limited support for integer values in printf/scanf"
depends on !REQUIRES_FLOAT_PRINTF && CBPRINTF_NANO
help
Include limited integer and no floating point support in
printf/scanf.
endchoice
if PICOLIBC_USE_MODULE
@ -101,17 +127,18 @@ config PICOLIBC_IO_C99_FORMATS
bool "support C99 format additions in printf/scanf"
default y
help
Includes support for hex floats (in floating-point version) and j, z,
t size modifiers.
Includes C99 printf and scanf support for j, z, t size
modifiers. C99 support is always included in the floating-point
variant
config PICOLIBC_IO_POS_ARGS
bool "Support POSIX positional args (e.g. %$1d) in printf/scanf"
default y
depends on !PICOLIBC_IO_FLOAT
depends on !PICOLIBC_IO_MINIMAL
help
Includes support for positional args (e.g. $1) in integer-only printf
and scanf. Positional args are always supported in the floating-point
versions.
Includes support for positional args (e.g. $1) in integer-only
printf and scanf. Positional args are always supported in the
floating-point variant.
config PICOLIBC_IO_FLOAT_EXACT
bool "support for exact float/string conversion"
@ -121,6 +148,21 @@ config PICOLIBC_IO_FLOAT_EXACT
This ensures that printf values with enough digits can be
fed to scanf and generate exactly the same binary value.
config PICOLIBC_IO_SMALL_ULTOA
bool "avoid soft division in printf"
default y
help
Replaces division and modulus by 10 with shifts and adds when
doing binary to decimal conversion in printf for 64-bit
values on 32-bit targets.
config PICOLIBC_IO_MINIMAL_LONG_LONG
bool "Include long long support in minimal printf"
depends on PICOLIBC_IO_MINIMAL
default y if CBPRINTF_FULL_INTEGRAL
help
Include long long support in the minimal picolibc printf code
config PICOLIBC_LOCALE_INFO
bool "support locales in libc functions"
help

View file

@ -31,7 +31,7 @@ choice CBPRINTF_INTEGRAL_CONV
# 01: 0% / 0 B (01 / 00)
config CBPRINTF_FULL_INTEGRAL
bool "Convert the full range of integer values"
select PICOLIBC_IO_LONG_LONG if PICOLIBC && !CBPRINTF_NANO
select PICOLIBC_IO_MINIMAL_LONG_LONG if PICOLIBC_IO_MINIMAL && PICOLIBC_USE_MODULE
help
Build cbprintf with buffers sized to support converting the full
range of all integral and pointer values.
@ -67,7 +67,6 @@ config CBPRINTF_FP_SUPPORT
bool "Floating point formatting in cbprintf"
default y if FPU
depends on CBPRINTF_COMPLETE
select PICOLIBC_IO_FLOAT if PICOLIBC
help
Build the cbprintf utility function with support for floating
point format specifiers. Selecting this increases stack size