ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zephyr RTOS 日志系统实战:5 个配置动作,把崩溃现场留在终端上

Zephyr RTOS 日志系统实战:5 个配置动作,把崩溃现场留在终端上 Zephyr RTOS 日志系统实战5 个配置动作把崩溃现场留在终端上【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr设备死机前那几十秒串口上一片空白你只能凭记忆猜它最后干了啥。这块我翻过车。差别在于Zephyr RTOS 日志子系统接好之后出问题前那一段会留在环形缓冲里崩溃现场直接落在终端上而不是留在你的脑子里。本文只讲照着能跑通的部分。4 行 prj.conf日志先跑起来先说结论开日志不用配很多项核心思路是输出不能卡住业务代码。我项目里最小可用就是这 4 行CONFIG_LOGy CONFIG_LOG_MODE_DEFERREDy CONFIG_LOG_BACKEND_UARTy CONFIG_LOG_DEFAULT_LEVEL3CONFIG_LOG_MODE_DEFERREDy消息先进缓冲再刷打日志不阻塞调用点。改成 IMMEDIATE同步模式的话每条日志都在调用现场格式化高优先级上下文里开销直接翻倍。CONFIG_LOG_BACKEND_UARTy串口后端开发期零成本。名字是 UART不是老教程里的 CONSOLE这个坑我下面会单独列。CONFIG_LOG_DEFAULT_LEVEL33 对应 INF没显式声明级别的模块输出到 INFO。想全静默就设 1但记得发布版还有更狠的裁剪手段。整个日志核心的选项都挂在 subsys/logging/Kconfig 里拿不准就翻着对照填。C 代码里注册模块命名第一天就要定死下面这段是驱动里的最小模板读失败打 ERR成功打 INF模块名就是后面过滤日志的钥匙#include zephyr/logging/log.h LOG_MODULE_REGISTER(sensor_drv, LOG_LEVEL_DBG); static int i2c_probe(struct device *bus) { int ret i2c_reg_read_byte(bus, REG_WHO_AM_I); if (ret 0) { LOG_ERR(总线层: 读失败 ret%d, ret); return ret; } if (ret ! WHO_AM_I_VAL) { LOG_WRN(寄存器层: whoami0x%02x 不符, ret); return -ENODEV; } return 0; }关键就一处LOG_ERR把错误码原样打出来事后光看数字就能定位是驱动没应答还是传输错了。一条日志中途经历了什么过滤 → 缓冲 → 后端三句话讲清这条链路日志宏展开后先过编译期级别这道闸过了才看运行时过滤两道闸都放行消息才进环形缓冲然后日志处理线程被唤醒负责格式化字符串再按你启用的后端逐条路由出去。一句话过滤 → 缓冲 → 后端。排障时卡在哪一环决定你查配置还是查线程。崩溃前最后一条日志怎么留用 LOG_PANIC让设备死机不可怕可怕的是死前记录全丢在缓冲里。做法是注册 fatal handler在里面调LOG_PANIC#include zephyr/logging/log.h void on_fatal(struct fatal_state *state) { LOG_PANIC(); /* 阻塞式刷空全部缓冲随后重启 */ }LOG_PANIC会强制日志线程把缓冲区清空、全部落盘再走重启流程于是死机前最后几条操作完整出现在终端上。别拿LOG_CRIT顶替它——那只是一条普通消息发完就走缓冲里还压着一堆没刷的。排障顺序我习惯按层收窄总线层、寄存器层、协议层的错误码分别打出来。日志停在总线层就查线和供电停在寄存器层就查器件和地址一层一层排除不用通读代码。后端怎么选看设备有没有口⚙️后端不是越多越好按场景挑一个主力的UART开发首选同一根线就再别跑别的协议。BLE给没引口的设备用基于 NUS 服务手机 App 直接收。单条通知受 MTU 限制超长消息要分包弱链路下可能丢包。FS文件系统写进 flash断电不丢适合事后取证。有写磨损高频打日志的场景别常开。参数怎么调才不拖慢系统性能裁剪我常年就动这几个旋钮CONFIG_LOG_PROCESS_THREADy CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD20 CONFIG_LOG_MAX_LEVEL3 CONFIG_LOG_SENSOR_DRV_LEVEL4LOG_PROCESS_THREAD 触发阈值格式化和 I/O 挪到低优先级线程业务代码塞完缓冲就走。阈值调大更省 CPU但日志延迟变长——崩溃取证的场景宁可调小。按模块抬级别全局留在 INF3只把正在查的sensor_drv抬到 DBG4总量可控、病灶看得清。发布版把LOG_MAX_LEVEL设成 1DEBUG/INFO 的代码在编译期就不进去比运行时关掉更省体积这才是真关。5 个我踩过的坑⚠️级别数字只有 0~40OFF、1ERR、2WRN、3INF、4DBG。照着老内核 0~6 的编号写 5语义直接跑偏看起来开了却什么都没有。PANIC 和 CRIT 不是一回事CRIT 只发一条消息就返回临终前用它最后十几条日志还压在缓冲里。要刷空就 PANIC。老教程的 CONSOLE 后端已改名当前主线的选项叫LOG_BACKEND_UART照旧文档配LOG_BACKEND_CONSOLE只会发现选项不存在。BLE 后端受 MTU 限制丢包会让日志缺中间误导判断。关键日志宁可拆短别贪长。运行时过滤不持久shell 里调的级别掉电重启就没了要长期生效还是写进 prj.conf。配置好之后读不出来、无响应这类问题的调试时间能从小时级压到分钟级——因为现场不在你脑子里在缓冲区里。三个入口文档 doc/services/logging/、完整示例 samples/subsys/logging/、核心实现 subsys/logging/log_core.c。【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表