Skip to content

Commit e7efb10

Browse files
committed
doc: misc: formatted_output: Add section for cbprintf packaging
Add documentation for cbprintf packaging. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent d61f3a7 commit e7efb10

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

doc/reference/misc/formatted_output.rst

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,84 @@ In addition :option:`CONFIG_CBPRINTF_NANO` can be used to revert back to
4040
the very space-optimized but limited formatter used for :c:func:`printk`
4141
before this capability was added.
4242

43+
.. _cbprintf_packaging:
44+
45+
Cbprintf Packaging
46+
******************
47+
48+
Typically, strings are formatted synchronously when a function from ``printf``
49+
family is called. However, there are cases when it is beneficial that formatting
50+
is deferred. In that case, a state (format string and arguments) must be captured.
51+
Such state forms a self-contained package which contains format string and
52+
arguments. Additionally, package contains copies of all strings which are
53+
part of a format string (format string or any ``%s`` argument) and are identifed
54+
as the one located in the read write memory. Package primary content resembles
55+
va_list stack frame thus standard formatting functions are used to process a
56+
package. Since package contains data which is processed as va_list frame,
57+
strict alignment must be maintained. Due to required padding, size of the
58+
package depends on alignment. When package is copied, it should be copied to a
59+
memory block with the same alignment as origin.
60+
61+
Package can be created using two methods:
62+
63+
* runtime - using :c:func:`cbprintf_package` or :c:func:`cbvprintf_package`. This
64+
method scans format string and based on detected format specifiers builds the
65+
package.
66+
* static - types of arguments are detected at compile time by the preprocessor
67+
and package is created as simple assignments to a provided memory. This method
68+
is significantly faster than runtime (more than 15 times) but has following
69+
limitations: requires ``_Generic`` keyword (C11 feature) to be supported by
70+
the compiler and can only create a package that is known to have no string
71+
arguments (``%s``). :c:macro:`CBPRINTF_MUST_RUNTIME_PACKAGE` can be used to
72+
determine at compile time if static packaging can be applied. Macro determines
73+
need for runtime packaging based on presence of char pointers in the argument
74+
list so there are cases when it will be false positive, e.g. ``%p`` with char
75+
pointer.
76+
77+
Several Kconfig options control behavior of the packaging:
78+
79+
* :option:`CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE`
80+
* :option:`CONFIG_CBPRINTF_STATIC_PACKAGE_CHECK_ALIGNMENT`
81+
82+
Cbprintf package format
83+
=======================
84+
85+
Format of the package contains paddings which are platform specific. Package consists
86+
of header which contains size of package (excluding appended strings) and number of
87+
appended strings. It is followed by the arguments which contains alignment paddings
88+
and resembles *va_list* stack frame. Finally, package optionally contains appended
89+
strings. Each string contains 1 byte header which contains index of the location
90+
where address argument is stored. During packaging address is set to null and
91+
before string formatting it is updated to point to the current string location
92+
within the package. Updating address argument must happen just before string
93+
formatting since address changes whenever package is copied.
94+
95+
+------------------+-------------------------------------------------------------------------+
96+
| Header | 1 byte: Argument list size including header and *fmt* (in 32 bit words) |
97+
| +-------------------------------------------------------------------------+
98+
| | sizeof(void \*)| 1 byte: Number of appended strings |
99+
| +-------------------------------------------------------------------------+
100+
| | platform specific padding to sizeof(void \*) |
101+
+------------------+-------------------------------------------------------------------------+
102+
| Arguments | Pointer to *fmt* (or null if *fmt* is appended to the package) |
103+
| +-------------------------------------------------------------------------+
104+
| | (optional padding for platform specific alignment) |
105+
| +-------------------------------------------------------------------------+
106+
| | argument 0 |
107+
| +-------------------------------------------------------------------------+
108+
| | (optional padding for platform specific alignment) |
109+
| +-------------------------------------------------------------------------+
110+
| | argument 1 |
111+
| +-------------------------------------------------------------------------+
112+
| | ... |
113+
+------------------+-------------------------------------------------------------------------+
114+
| Appended | 1 byte: Index within the package to the location of associated argument |
115+
| +-------------------------------------------------------------------------+
116+
| strings | Null terminated string |
117+
| +-------------------------------------------------------------------------+
118+
| | ... |
119+
+------------------+-------------------------------------------------------------------------+
120+
43121
.. warning::
44122

45123
If :option:`CONFIG_MINIMAL_LIBC` is selected in combination with

0 commit comments

Comments
 (0)