From 805aa10b6694e24760da5cbad6e20d8a7530de82 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 31 Jan 2023 19:31:03 -0800 Subject: [PATCH] doc/develop: Add picolibc documentation This describes the capabilities offered by Picolibc along with some of the requirements applications have when using it. Signed-off-by: Keith Packard --- doc/develop/languages/c/index.rst | 1 + doc/develop/languages/c/picolibc.rst | 157 +++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 doc/develop/languages/c/picolibc.rst diff --git a/doc/develop/languages/c/index.rst b/doc/develop/languages/c/index.rst index 8ea3694074cb3..a949b5e86a22f 100644 --- a/doc/develop/languages/c/index.rst +++ b/doc/develop/languages/c/index.rst @@ -60,6 +60,7 @@ application. minimal_libc.rst newlib.rst + picolibc.rst .. _`C Standard Library`: https://en.wikipedia.org/wiki/C_standard_library diff --git a/doc/develop/languages/c/picolibc.rst b/doc/develop/languages/c/picolibc.rst new file mode 100644 index 0000000000000..7428f3c85a194 --- /dev/null +++ b/doc/develop/languages/c/picolibc.rst @@ -0,0 +1,157 @@ +.. _c_library_picolibc: + +Picolibc +######## + +`Picolibc`_ is a complete C library implementation written for the +embedded systems, targeting `C17 (ISO/IEC 9899:2018)`_ and `POSIX 2018 +(IEEE Std 1003.1-2017)`_ standards. Picolibc is an external open +source project which is provided for Zephyr as a module, and included +as part of the :ref:`toolchain_zephyr_sdk` in precompiled form for +each supported architecture (:file:`libc.a`). + +.. note:: + Picolibc is also available for other 3rd-party toolchains, such as + :ref:`toolchain_gnuarmemb`. + +Zephyr implements the “API hook” functions that are invoked by the C +standard library functions in the Picolibc. These hook functions are +implemented in :file:`lib/libc/picolibc/libc-hooks.c` and translate +the library internal system calls to the equivalent Zephyr API calls. + +.. _`Picolibc`: https://github.com/picolibc/picolibc +.. _`C17 (ISO/IEC 9899:2018)`: https://www.iso.org/standard/74528.html +.. _`POSIX 2018 (IEEE Std 1003.1-2017)`: https://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html + +Picolibc Module +=============== + +When built as a Zephyr module, there are several configuration knobs +available to adjust the feature set in the library, balancing what the +library supports versus the code size of the resulting +functions. Because the standard C++ library must be compiled for the +target C library, the Picolibc module cannot be used with applications +which use the standard C++ library. Building the Picolibc module will +increase the time it takes to compile the application. + +The Picolibc module can be enabled by selecting +:kconfig:option:`CONFIG_PICOLIBC_USE_MODULE` in the application +configuration file. + +Toolchain Picolibc +================== + +Starting with version 0.16, the Zephyr SDK includes precompiled +versions of Picolibc for every target architecture, along with +precompiled versions of libstdc++. + +The toolchain version of Picolibc can be enabled by de-selecting +:kconfig:option:`CONFIG_PICOLIBC_USE_MODULE` in the application +configuration file. + +Formatted Output +**************** + +Picolibc supports all standard C formatted input and output functions, +including :c:func:`printf`, :c:func:`fprintf`, :c:func:`sprintf` and +:c:func:`sscanf`. + +Picolibc formatted input and output function implementation supports +all format specifiers defined by the C17 and POSIX 2018 standards with +the following exceptions: + +* Floating point format specifiers (e.g. ``%f``) require + :kconfig:option:`CONFIG_PICOLIBC_IO_FLOAT`. + +* Long long format specifiers (e.g. ``%lld``) require + :kconfig:option:`CONFIG_PICOLIBC_IO_LONG_LONG`. This option is + automatically enabled with :kconfig:option:`CONFIG_PICOLIBC_IO_FLOAT`. + +Printk, cbprintf and friends +**************************** + +When using Picolibc, Zephyr formatted output functions are +implemented in terms of stdio calls. This includes: + + * printk, snprintk and vsnprintk + * cbprintf and cbvprintf + * fprintfcb, vfprintfcb, printfcb, vprintfcb, snprintfcb and vsnprintfcb + +When using tagged args +(:kconfig:option:`CONFIG_CBPRINTF_PACKAGE_SUPPORT_TAGGED_ARGUMENTS` and +:c:macro:`CBPRINTF_PACKAGE_ARGS_ARE_TAGGED`), calls to cbpprintf will +not use Picolibc, so formatting of output using those code will differ +from Picolibc results as the cbprintf functions are not completely +C/POSIX compliant. + +Math Functions +************** + +Picolibc provides full C17/`IEEE STD 754-2019`_ support for float, +double and long double math operations, except for long double +versions of the Bessel functions. + +.. _`IEEE STD 754-2019`: https://ieeexplore.ieee.org/document/8766229 + +Thread Local Storage +******************** + +Picolibc uses Thread Local Storage (TLS) (where supported) for data +which is supposed to remain local to each thread, like +:c:var:`errno`. This means that TLS support is enabled when using +Picolibc. As all TLS variables are allocated out of the thread stack +area, this can affect stack size requirements by a few bytes. + +C Library Local Variables +************************* + +Picolibc uses a few internal variables for things like heap +management. These are collected in a dedicated memory partition called +:c:var:`z_libc_partition`. Applications using +:kconfig:option:`CONFIG_USERSPACE` and memory domains must ensure that +this partition is included in any domain active during Picolibc calls. + +Dynamic Memory Management +************************* + +Picolibc implements an internal heap allocator to manage the memory +blocks used by the standard dynamic memory management interface +functions (for example, :c:func:`malloc` and :c:func:`free`). + +The only interface between the Picolibc dynamic memory management +functions and the Zephyr-side libc hooks is the :c:func:`sbrk` +function, which is used by Picolibc to manage the size of the +memory pool reserved for its internal heap allocator. + +The :c:func:`sbrk` hook function, implemented in +:file:`libc-hooks.c`, handles the memory pool size change requests +from Picolibc and ensures that the Picolibc internal heap allocator +memory pool size does not exceed the amount of available memory space +by returning an error when the system is out of memory. + +When userspace is enabled, the Picolibc internal heap allocator memory +pool is placed in a dedicated memory partition called +:c:var:`z_malloc_partition`, which can be accessed from the user mode +threads. + +The amount of memory space available for the Picolibc heap is set by +the :kconfig:option:`CONFIG_PICOLIBC_HEAP_SIZE`, or the amount of free +memory available, whichever is smallest. Set +:kconfig:option:`CONFIG_PICOLIBC_HEAP_SIZE` to -1 to always use the +amount of free memory available. + +* When MMU is enabled (:kconfig:option:`CONFIG_MMU` is selected), the + amount of free memory available is determined at runtime with the + :c:func:`k_mem_free_get` function. + +* When MPU is enabled and the MPU requires power-of-two partition + size, then :kconfig:option:`CONFIG_PICOLIBC_HEAP_SIZE` (if not -1) + must be set to a power of two value. + +* Otherwise, the amount of free memory available is equal to the + amount of unallocated memory in the SRAM region as determined at + compile time. + +The standard dynamic memory management interface functions implemented +by Picolibc are thread safe and may be simultaneously called by +multiple threads.