Skip to content

Commit a900a2e

Browse files
author
Nicolas Pitre
committed
lib: cbprintf: add support for deferred formatting
In applications like logging the call site where arguments to formatting are available may not be suitable for performing the formatting, e.g. when the output operation can sleep. Add API that supports capturing data that may be transient into a buffer that can be saved, and API that then produces the output later using the packaged arguments. [ Documentation and commit log from Peter Bigot. ] Signed-off-by: Nicolas Pitre <[email protected]> Signed-off-by: Peter Bigot <[email protected]>
1 parent 90722ad commit a900a2e

File tree

4 files changed

+673
-0
lines changed

4 files changed

+673
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@
462462
/lib/gui/ @vanwinkeljan
463463
/lib/open-amp/ @arnopo
464464
/lib/os/ @dcpleung @nashif @andyross
465+
/lib/os/cbprintf_packaged.c @npitre
465466
/lib/posix/ @pfalcon
466467
/lib/cmsis_rtos_v2/ @nashif
467468
/lib/cmsis_rtos_v1/ @nashif

include/sys/cbprintf.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <stdarg.h>
1111
#include <stddef.h>
12+
#include <stdint.h>
1213
#include <toolchain.h>
1314

1415
#ifdef CONFIG_CBPRINTF_LIBC_SUBSTS
@@ -44,6 +45,102 @@ extern "C" {
4445
*/
4546
typedef int (*cbprintf_cb)(/* int c, void *ctx */);
4647

48+
/** @brief Capture state required to output formatted data later.
49+
*
50+
* Like cbprintf() but instead of processing the arguments and emitting the
51+
* formatted results immediately all arguments are captured so this can be
52+
* done in a different context, e.g. when the output function can block.
53+
*
54+
* In addition to the values extracted from arguments this will ensure that
55+
* copies are made of the necessary portions of any string parameters that are
56+
* not confirmed to be stored in read-only memory (hence assumed to be safe to
57+
* refer to directly later).
58+
*
59+
* @param packaged pointer to where the packaged data can be stored. Pass a
60+
* null pointer to store nothing but still calculate the total space required.
61+
* The data stored here is relocatable, that is it can be moved to another
62+
* contiguous block of memory. The pointer must be aligned to a multiple of
63+
* the largest element in the argument list.
64+
*
65+
* @param len this must be set to the number of bytes available at @p packaged.
66+
* Ignored if @p packaged is NULL.
67+
*
68+
* @param format a standard ISO C format string with characters and conversion
69+
* specifications.
70+
*
71+
* @param ... arguments corresponding to the conversion specifications found
72+
* within @p format.
73+
*
74+
* @retval nonegative the number of bytes successfully stored at @p packaged.
75+
* This will not exceed @p len.
76+
* @retval -EINVAL if @p format is not acceptable
77+
* @retval -ENOSPC if @p packaged was not null and the space required to store
78+
* exceed @p len.
79+
*/
80+
__printf_like(3, 4)
81+
int cbprintf_package(void *packaged,
82+
size_t len,
83+
const char *format,
84+
...);
85+
86+
/** @brief Capture state required to output formatted data later.
87+
*
88+
* Like cbprintf() but instead of processing the arguments and emitting the
89+
* formatted results immediately all arguments are captured so this can be
90+
* done in a different context, e.g. when the output function can block.
91+
*
92+
* In addition to the values extracted from arguments this will ensure that
93+
* copies are made of the necessary portions of any string parameters that are
94+
* not confirmed to be stored in read-only memory (hence assumed to be safe to
95+
* refer to directly later).
96+
*
97+
* @param packaged pointer to where the packaged data can be stored. Pass a
98+
* null pointer to store nothing but still calculate the total space required.
99+
* The data stored here is relocatable, that is it can be moved to another
100+
* contiguous block of memory. The pointer must be aligned to a multiple of
101+
* the largest element in the argument list.
102+
*
103+
* @param len this must be set to the number of bytes available at @p packaged.
104+
* Ignored if @p packaged is NULL.
105+
*
106+
* @param format a standard ISO C format string with characters and conversion
107+
* specifications.
108+
*
109+
* @param ap captured stack arguments corresponding to the conversion
110+
* specifications found within @p format.
111+
*
112+
* @retval nonegative the number of bytes successfully stored at @p packaged.
113+
* This will not exceed @p len.
114+
* @retval -EINVAL if @p format is not acceptable
115+
* @retval -ENOSPC if @p packaged was not null and the space required to store
116+
* exceed @p len.
117+
*/
118+
int cbvprintf_package(void *packaged,
119+
size_t len,
120+
const char *format,
121+
va_list ap);
122+
123+
/** @brief Generate the output for a previously captured format
124+
* operation.
125+
*
126+
* @param out the function used to emit each generated character.
127+
*
128+
* @param ctx context provided when invoking out
129+
*
130+
* @param packaged the data required to generate the formatted output, as
131+
* captured by cbprintf_package() or cbvprintf_package(). The alignment
132+
* requirement on this data is the same as when it was initially created.
133+
*
134+
* @note Memory indicated by @p packaged will be modified in a non-destructive
135+
* way, meaning that it could still be reused with this function again.
136+
*
137+
* @return the number of characters printed, or a negative error value
138+
* returned from invoking @p out.
139+
*/
140+
int cbpprintf(cbprintf_cb out,
141+
void *ctx,
142+
void *packaged);
143+
47144
/** @brief *printf-like output through a callback.
48145
*
49146
* This is essentially printf() except the output is generated

lib/os/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ zephyr_sources_ifdef(CONFIG_BASE64 base64.c)
44

55
zephyr_sources(
66
cbprintf.c
7+
cbprintf_packaged.c
78
crc32c_sw.c
89
crc32_sw.c
910
crc16_sw.c

0 commit comments

Comments
 (0)