doc: misc: formatted_output: Add section for cbprintf packaging

Add documentation for cbprintf packaging.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-03-29 22:38:03 +02:00 committed by Anas Nashif
commit fb4d945b82

View file

@ -40,6 +40,84 @@ In addition :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 contains copies of all strings which are
part of a format string (format string or any ``%s`` argument) and are identifed
as the one located in the read write memory. 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 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 can only create a package that is known to have no string
arguments (``%s``). :c:macro:`CBPRINTF_MUST_RUNTIME_PACKAGE` can be used to
determine at compile time if static packaging can be applied. Macro determines
need for runtime packaging based on presence of char pointers in the argument
list so there are cases when it will be false positive, e.g. ``%p`` with char
pointer.
Several Kconfig options control behavior of the packaging:
* :option:`CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE`
* :option:`CONFIG_CBPRINTF_STATIC_PACKAGE_CHECK_ALIGNMENT`
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. 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 appended strings |
| +-------------------------------------------------------------------------+
| | 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 |
| +-------------------------------------------------------------------------+
| | ... |
+------------------+-------------------------------------------------------------------------+
| Appended | 1 byte: Index within the package to the location of associated argument |
| +-------------------------------------------------------------------------+
| strings | Null terminated string |
| +-------------------------------------------------------------------------+
| | ... |
+------------------+-------------------------------------------------------------------------+
.. warning::
If :option:`CONFIG_MINIMAL_LIBC` is selected in combination with