格式化输出:应用接口与后端
本页依据 文档基线与后续更新 中记录的 Zephyr main 快照更新。
选择输出接口时,应考虑调用上下文、输出设备、是否需要过滤,以及数据是否要延后处理。
接口 |
头文件 |
用途与路径 |
|---|---|---|
|
|
简单诊断输出;可通过配置导入日志系统 |
|
|
所选 C 库的标准输出或内存格式化 |
|
|
向指定 Shell 实例输出,与命令交互协调 |
|
|
带来源、等级、过滤和后端的日志 |
|
|
回调格式化或避免引入独立格式化实现 |
printk
启用 CONFIG_PRINTK 及目标所需的控制台配置。输出位置由架构、控制台驱动和配置决定,
不能从 API 名称推断它一定使用 UART。
CONFIG_LOG_PRINTK 会把 printk 导入日志,延后日志模式中它也可能延后显示。
#include <zephyr/sys/printk.h>
void report_status(int status)
{
printk("status=%d\n", status);
}
频繁输出会影响处理时间。即使某一输出路径支持 ISR 调用,也不表示任意后端或
任意 C 库 printf 都适合在中断里使用。
标准 C 库输出
Zephyr 可选择不同 C 库,printf 支持的格式与浮点配置、内存使用随之变化。
例如 cbprintf 的浮点选项与某个 libc 的 printf 浮点选项不能直接互换。
优先使用带长度的内存格式化并检查截断:
#include <stdio.h>
#include <errno.h>
int format_status(char *buffer, size_t capacity, int status)
{
int rc = snprintf(buffer, capacity, "status=%d", status);
if (rc < 0) {
return rc;
}
if ((size_t)rc >= capacity) {
return -ENOSPC;
}
return 0;
}
snprintf 成功返回原本需要的字符数,不包含结尾 NUL,
返回值大于等于容量表示输出被截断。字符串格式不能来自未经控制的外部输入。
Shell 与日志
Shell 命令回调使用 shell_print(sh, ...)、shell_error(sh, ...),
通常由这些接口追加换行,避免额外重复输出。
日志使用 LOG_* 宏记录来源和等级,生产代码可按模块配置过滤。
它们还需配置合适的传输后端,详见 Shell 系统使用指南 和
日志系统使用指南。
当前 logger 会打包格式串和参数;延后模式把格式化及后端输出安排在后续处理时机。 Shell 与 logger 可以共享服务能力,但不能简单描述为“所有接口最后都走同一个 UART”。 多个后端、日志重定向、不同 libc 和自定义输出钩子都会改变实际路径。
性能与资源
格式转换、消息缓冲、输出带宽和处理线程栈都影响资源。 浮点格式化可能增加代码与栈,长 hexdump 会增加日志缓冲压力。 在实时路径中记录必要信息,将可延后工作放到合适线程,并通过构建配置和测量确定成本。