|  | .. _formatted_output: | 
|  |  | 
|  | Formatted Output | 
|  | ################ | 
|  |  | 
|  | Applications as well as Zephyr itself requires infrastructure to format | 
|  | values for user consumption.  The standard C99 library ``*printf()`` | 
|  | functionality fulfills this need for streaming output devices or memory | 
|  | buffers, but in an embedded system devices may not accept streamed data | 
|  | and memory may not be available to store the formatted output. | 
|  |  | 
|  | Internal Zephyr API traditionally provided this both for | 
|  | :c:func:`printk` and for Zephyr's internal minimal libc, but with | 
|  | separate internal interfaces.  Logging, tracing, shell, and other | 
|  | applications made use of either these APIs or standard libc routines | 
|  | based on build options. | 
|  |  | 
|  | The :c:func:`cbprintf` public APIs convert C99 format strings and | 
|  | arguments, providing output produced one character at a time through a | 
|  | callback mechanism, replacing the original internal functions and | 
|  | providing support for almost all C99 format specifications.  Existing | 
|  | use of ``s*printf()`` C libraries in Zephyr can be converted to | 
|  | :c:func:`snprintfcb()` to avoid pulling in libc implementations. | 
|  |  | 
|  | Several Kconfig options control the set of features that are enabled, | 
|  | allowing some control over features and memory usage: | 
|  |  | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_FULL_INTEGRAL` | 
|  | or :kconfig:option:`CONFIG_CBPRINTF_REDUCED_INTEGRAL` | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_FP_SUPPORT` | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_FP_A_SUPPORT` | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_FP_ALWAYS_A` | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_N_SPECIFIER` | 
|  |  | 
|  | :kconfig:option:`CONFIG_CBPRINTF_LIBC_SUBSTS` can be used to provide functions | 
|  | that behave like standard libc functions but use the selected cbprintf | 
|  | formatter rather than pulling in another formatter from libc. | 
|  |  | 
|  | In addition :kconfig:option:`CONFIG_CBPRINTF_NANO` can be used to revert back to | 
|  | the very space-optimized but limited formatter used for :c:func:`printk` | 
|  | before this capability was added. | 
|  |  | 
|  | .. _cbprintf_packaging: | 
|  |  | 
|  | Cbprintf Packaging | 
|  | ****************** | 
|  |  | 
|  | Typically, strings are formatted synchronously when a function from ``printf`` | 
|  | family is called. However, there are cases when it is beneficial that formatting | 
|  | is deferred. In that case, a state (format string and arguments) must be captured. | 
|  | Such state forms a self-contained package which contains format string and | 
|  | arguments. Additionally, package may contain copies of strings which are | 
|  | part of a format string (format string or any ``%s`` argument). Package primary | 
|  | content resembles va_list stack frame thus standard formatting functions are | 
|  | used to process a package. Since package contains data which is processed as | 
|  | va_list frame, strict alignment must be maintained. Due to required padding, | 
|  | size of the package depends on alignment. When package is copied, it should be | 
|  | copied to a memory block with the same alignment as origin. | 
|  |  | 
|  | Package can have following variants: | 
|  |  | 
|  | * **Self-contained** - non read-only strings appended to the package. String can be | 
|  | formatted from such package as long as there is access to read-only string | 
|  | locations. Package may contain information where read-only strings are located | 
|  | within the package. That information can be used to convert packet to fully | 
|  | self-contained package. | 
|  | * **Fully self-contained** - all strings are appended to the package. String can be | 
|  | formatted from such package without any external data. | 
|  | * **Transient**- only arguments are stored. Package contain information | 
|  | where pointers to non read-only strings are located within the package. Optionally, | 
|  | it may contain read-only string location information. String can be formatted | 
|  | from such package as long as non read-only strings are still valid and read-only | 
|  | strings are accessible. Alternatively, package can be converted to **self-contained** | 
|  | package or **fully self-contained** if information about read-only string | 
|  | locations is present in the package. | 
|  |  | 
|  | Package can be created using two methods: | 
|  |  | 
|  | * runtime - using :c:func:`cbprintf_package` or :c:func:`cbvprintf_package`. This | 
|  | method scans format string and based on detected format specifiers builds the | 
|  | package. | 
|  | * static - types of arguments are detected at compile time by the preprocessor | 
|  | and package is created as simple assignments to a provided memory. This method | 
|  | is significantly faster than runtime (more than 15 times) but has following | 
|  | limitations: requires ``_Generic`` keyword (C11 feature) to be supported by | 
|  | the compiler and cannot distinguish between ``%p`` and ``%s`` if char pointer | 
|  | is used. It treats all (unsigned) char pointers as ``%s`` thus it will attempt | 
|  | to append string to a package. It can be handled correctly during conversion | 
|  | from **transient** package to **self-contained** package using | 
|  | :c:macro:`CBPRINTF_PACKAGE_CONVERT_PTR_CHECK` flag. However, it requires access | 
|  | to the format string and it is not always possible thus it is recommended to | 
|  | cast char pointers used for ``%p`` to ``void *``. There is a logging warning | 
|  | generated by :c:func:`cbprintf_package_convert` called with | 
|  | :c:macro:`CBPRINTF_PACKAGE_CONVERT_PTR_CHECK` flag when char pointer is used with | 
|  | ``%p``. | 
|  |  | 
|  |  | 
|  | Several Kconfig options control behavior of the packaging: | 
|  |  | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE` | 
|  | * :kconfig:option:`CONFIG_CBPRINTF_STATIC_PACKAGE_CHECK_ALIGNMENT` | 
|  |  | 
|  | Cbprintf package conversion | 
|  | =========================== | 
|  |  | 
|  | It is possible to convert package to a variant which contains more information, e.g | 
|  | **transient** package can be converted to **self-contained**. Conversion to | 
|  | **fully self-contained** package is possible if :c:macro:`CBPRINTF_PACKAGE_ADD_RO_STR_POS` | 
|  | flag was used when package was created. | 
|  |  | 
|  | :c:func:`cbprintf_package_copy` is used to calculate space needed for the new | 
|  | package and to copy and convert a package. | 
|  |  | 
|  | Cbprintf package format | 
|  | ======================= | 
|  |  | 
|  | Format of the package contains paddings which are platform specific. Package consists | 
|  | of header which contains size of package (excluding appended strings) and number of | 
|  | appended strings. It is followed by the arguments which contains alignment paddings | 
|  | and resembles *va_list* stack frame. It is followed by data associated with character | 
|  | pointer arguments used by the string which are not appended to the string (but may | 
|  | be appended later by :c:func:`cbprinf_package_convert`). Finally, package, optionally, | 
|  | contains appended strings. Each string contains 1 byte header which contains index | 
|  | of the location where address argument is stored. During packaging address is set | 
|  | to null and before string formatting it is updated to point to the current string | 
|  | location within the package. Updating address argument must happen just before string | 
|  | formatting since address changes whenever package is copied. | 
|  |  | 
|  | +------------------+-------------------------------------------------------------------------+ | 
|  | | Header           | 1 byte: Argument list size including header and *fmt* (in 32 bit words) | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | | sizeof(void \*)  | 1 byte: Number of strings appended to the package                       | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | 1 byte: Number of read-only string argument locations                   | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | 1 byte: Number of transient string argument locations                   | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | platform specific padding to sizeof(void \*)                            | | 
|  | +------------------+-------------------------------------------------------------------------+ | 
|  | | Arguments        | Pointer to *fmt* (or null if *fmt* is appended to the package)          | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | (optional padding for platform specific alignment)                      | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | argument 0                                                              | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | (optional padding for platform specific alignment)                      | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | argument 1                                                              | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | ...                                                                     | | 
|  | +------------------+-------------------------------------------------------------------------+ | 
|  | | String location  | Indexes of words within the package where read-only strings are located | | 
|  | | information      +-------------------------------------------------------------------------+ | 
|  | | (optional)       | Pairs of argument index and argument location index where transient     | | 
|  | |                  | strings are located                                                     | | 
|  | +------------------+-------------------------------------------------------------------------+ | 
|  | | Appended         | 1 byte: Index within the package to the location of associated argument | | 
|  | | strings          +-------------------------------------------------------------------------+ | 
|  | | (optional)       | Null terminated string                                                  | | 
|  | |                  +-------------------------------------------------------------------------+ | 
|  | |                  | ...                                                                     | | 
|  | +------------------+-------------------------------------------------------------------------+ | 
|  |  | 
|  | .. warning:: | 
|  |  | 
|  | If :kconfig:option:`CONFIG_MINIMAL_LIBC` is selected in combination with | 
|  | :kconfig:option:`CONFIG_CBPRINTF_NANO` formatting with C standard library | 
|  | functions like ``printf`` or ``snprintf`` is limited.  Among other | 
|  | things the ``%n`` specifier, most format flags, precision control, and | 
|  | floating point are not supported. | 
|  |  | 
|  | .. _cbprintf_packaging_limitations: | 
|  |  | 
|  | Limitations and recommendations | 
|  | =============================== | 
|  |  | 
|  | * C11 ``_Generic`` support is required by the compiler to use static (fast) packaging. | 
|  | * It is recommended to cast any character pointer used with ``%p`` format specifier to | 
|  | other pointer type (e.g. ``void *``). If format string is not accessible then only | 
|  | static packaging is possible and it will append all detected strings. Character pointer | 
|  | used for ``%p`` will be considered as string pointer. Copying from unexpected location | 
|  | can have serious consequences (e.g., memory fault or security violation). | 
|  |  | 
|  | API Reference | 
|  | ************* | 
|  |  | 
|  | .. doxygengroup:: cbprintf_apis |