Zephyr学习 - 第二章 - 5:常见警告、配置追踪与第二章总结
02-5常见警告、配置追踪与第二章总结验证方式故障配置、生成文件、Zephyr Kconfig 前端源码、native_sim/native/64验证结论源码确认 编译确认 模拟确认1. 本节目标遇到下面的问题时不靠猜测我明明在 prj.conf 中写了 CONFIG_FOOy为什么没有生效 为什么出现 Kconfig warning 这个值到底来自哪个配置文件 为什么 .config 中是 y但功能源码仍没有编译本节建立一套固定排查顺序并用四个错误配置验证常见诊断信息。2. 先记住请求值不等于最终值配置片段中的请求 board defconfig 多个 conf/overlay 对应的配置输入 Kconfig 的 depends on/default/select/imply/range/visibility - Kconfig 求值 - zephyr/.config 最终值 - autoconf.h / CMake CONFIG_* 变量 - C 代码和构建系统消费因此prj.conf只能证明“请求过什么”.config才能证明“最终得到什么”。3. 推荐的七步配置追踪法以下顺序适用于普通 Zephyr 功能。第 1 步确认正在检查正确的 build directory不同 build directory 可以拥有完全不同的板子、配置文件和.config。rg^BOARD:|^CONF_FILE:\/mnt/c/study/1-zephyr/work/ch02_enabled/CMakeCache.txt本实验能看到CONF_FILE:STRING/mnt/c/study/1-zephyr/labs/ch02_kconfig/prj.conf修改了板子、主要配置或怀疑缓存时使用 pristine buildwest build...-palways第 2 步确认实际合并了哪些配置文件查看sed-n/kconfig:/,/toolchain:/p\/mnt/c/study/1-zephyr/work/ch02_enabled/build_info.yml实际结果包括kconfig:files:-.../native_sim_64_defconfig-/mnt/c/study/1-zephyr/labs/ch02_kconfig/prj.confuser-files:-/mnt/c/study/1-zephyr/labs/ch02_kconfig/prj.conf它回答的是本次构建到底读取了哪些输入文件编译确认第 3 步查 symbol 在哪里定义和赋值查询 Kconfig 定义时不要带CONFIG_前缀rg-n^\s*(menu)?config LEARN_PERIOD_MS\b\/mnt/c/study/1-zephyr/labs/ch02_kconfig\/home/yff/project/zephyr查询配置片段赋值时要带CONFIG_rg-nCONFIG_LEARN_PERIOD_MS\/mnt/c/study/1-zephyr/labs/ch02_kconfig\-g*.conf区分两种名字Kconfig 定义config LEARN_PERIOD_MS 配置和 C 代码CONFIG_LEARN_PERIOD_MS第 4 步检查 Kconfig 约束在 symbol 定义附近重点找depends on if / endif range prompt 是否存在 default select imply还可以使用west build\--build-dir /mnt/c/study/1-zephyr/work/ch02_enabled\-tmenuconfig在menuconfig中按/搜索 symbol可以查看当前值、定义位置和依赖。第 5 步以.config为最终事实rg-nCONFIG_LEARN_(FEATURE|PERIOD_MS)\/mnt/c/study/1-zephyr/work/ch02_enabled/zephyr/.config实际结果CONFIG_LEARN_FEATUREy CONFIG_LEARN_PERIOD_MS250如果 symbol 因依赖而完全不可见它甚至可能不出现在.config中。不要把“找不到”误认为 Kconfig 没有解析它应继续检查定义和依赖。第 6 步确认 C 代码实际得到什么rg-nCONFIG_LEARN_(FEATURE|PERIOD_MS)\/mnt/c/study/1-zephyr/work/ch02_enabled/zephyr/include/generated/zephyr/autoconf.h实际结果#defineCONFIG_LEARN_FEATURE1#defineCONFIG_LEARN_PERIOD_MS250关闭的 bool 通常不会生成值为0的宏而是没有这个#define。因此常见写法是#ifdefined(CONFIG_FOO)#endifif(IS_ENABLED(CONFIG_FOO)){}第 7 步若配置正确继续追踪 CMake 和链接当.config已经是y但功能仍不存在时问题可能已不在 Kconfig.config - CMakeLists.txt - compile_commands.json - .obj - zephyr.elf / zephyr.map这是 02-4 建立的检查链路。4. 实验一依赖不满足请求 y 但最终为 n配置CONFIG_LEARN_REQUIRED_BACKENDn CONFIG_LEARN_DEPENDS_CLIENTyKconfigconfig LEARN_DEPENDS_CLIENT bool Client using depends on depends on LEARN_REQUIRED_BACKEND构建命令cd~/project/exportZEPHYR_SDK_INSTALL_DIR/home/yff/zephyr-sdk/zephyr-sdk-0.17.1sourcezephyr/zephyr-env.sh west build\-bnative_sim/native/64\/mnt/c/study/1-zephyr/labs/ch02_kconfig\--build-dir /mnt/c/study/1-zephyr/work/ch02_warn_depends\-palways\---DCONF_FILEdepends_invalid.conf实际 warning 核心内容LEARN_DEPENDS_CLIENT ... was assigned the value y but got the value n. Check these unsatisfied dependencies: LEARN_REQUIRED_BACKEND (n).本地 Zephyr 4.1.0-rc1 中这一类“请求值与最终值不一致”的提示没有终止构建。程序实际运行输出depends: backend0 client0最终.config中后端为 n依赖它的 client 因不可见而没有写入输出# CONFIG_LEARN_REQUIRED_BACKEND is not set结论写入y不能突破depends on。模拟确认5. 实验二直接给隐藏 symbol 赋值错误配置CONFIG_LEARN_VISIBLE_VALUE42 CONFIG_LEARN_HIDDEN_MIRROR99对应定义config LEARN_HIDDEN_MIRROR int default LEARN_VISIBLE_VALUE因为没有 prompt它不是供用户直接配置的 symbol。实际错误LEARN_HIDDEN_MIRROR ... is assigned in a configuration file, but is not directly user-configurable (has no prompt). It gets its value indirectly from other symbols.结果CMake 配置阶段退出返回码为 1没有生成最终.config。正确做法是配置它的输入CONFIG_LEARN_VISIBLE_VALUE42让隐藏 symbol 通过default LEARN_VISIBLE_VALUE得到 42。编译确认6. 实验三整数超出 range错误配置range_invalid.confCONFIG_LEARN_FEATUREy CONFIG_LEARN_PERIOD_MS9000定义允许的范围range 10 5000实际信息user value 9000 ... ignored due to being outside the active range ([10, 5000]) -- falling back on defaults error: Aborting due to Kconfig warnings虽然信息说会回退到默认值 1000但本次 Zephyr 构建仍因 warning 退出没有产生可用的最终构建。结论不要依赖“自动回退”掩盖错误输入应修正配置片段。编译确认7. 实验四symbol 名称拼错或已被删除错误配置typo_invalid.confCONFIG_LEARN_VERBOESy正确名称应为CONFIG_LEARN_VERBOSE实际信息attempt to assign the value y to the undefined symbol LEARN_VERBOES error: Aborting due to Kconfig warnings常见原因名称拼写错误symbol 在当前 Zephyr 版本已改名或删除定义它的模块没有进入 Kconfig tree把 Devicetree 属性名或 C 宏误当成 Kconfig symbol。第一步应搜索定义而不是立即新增一个同名 Kconfigrg-n^\s*(menu)?config LEARN_VERBOES\b\/home/yff/project/\/mnt/c/study/1-zephyr/labs/ch02_kconfig搜索不到即可证明当前 Kconfig tree 的源码中没有这个定义。编译确认8. 为什么有的 warning 能继续有的会终止本地 Zephyr 前端源码zephyr/scripts/kconfig/kconfig.py关键行为约第 50 行手写配置片段会开启“给未定义 symbol 赋值”的检查约第 83 行检查给无 prompt symbol 的直接赋值约第 127 行需要失败的 warning 会触发Aborting due to Kconfig warnings约第 167 行生成“assigned … but got …”提示并列出缺失依赖。源码注释明确说明“请求值与最终值不一致”这一类当前暂时保留为 warning其他 Kconfig warnings 通常会转成错误。因此不能只看到单词warning就猜测退出结果要观察是否出现 Aborting due to Kconfig warnings west build 的返回码 最终 .config 是否生成 zephyr.elf 是否生成源码确认9. 常见现象速查表现象优先检查典型原因请求 y最终 nsymbol 的依赖depends on不满足symbol 在 menuconfig 中找不到定义、父级if、模块是否载入不在 Kconfig tree 或不可见undefined symbolrg搜索config NAME拼写、改名、模块缺失not directly user-configurablesymbol 是否有 prompt错误设置隐藏 symbolint/hex 值被忽略range及其条件超出 active range.configy但 C 宏异常autoconf.h和 build directory看错构建目录或缓存.configy但文件未编译CMake 和compile_commands.json目录/源码未加入 targetobject 有但 ELF 无 symbolmap、引用关系、section GC链接器移除未引用 section10. 第二章知识地图02-1配置请求、合并和 depends onprj.conf 是请求 .config 是最终值 depends on 限制 symbol 的可见性和最大值02-2select、imply 和 depends ondepends on要求前置条件 select强制打开被选择项适合无依赖的内部 helper imply软建议允许用户覆盖02-3default、可见性和 menuconfigdefault 按顺序选择第一个成立项 显式有效赋值优先于 default 无 prompt symbol 通常不能在 conf 中直接设置02-4Kconfig 控制 CMake 和源码编译Kconfig - CMake - compiler - object - linker - ELF - runtime02-5warning 和配置追踪输入文件 - symbol 定义/约束 - .config - autoconf.h - CMake/compile_commands - object/ELF第二章最重要的三句话prj.conf是配置请求.config是最终事实Kconfig 决定“功能是否成立”CMake 决定“源码是否进入构建”排查配置问题要沿生成链路取证不要只看某一个文件。11. 本节练习与自测练习一解释 warning阅读labs/ch02_kconfig/depends_invalid.conf labs/ch02_kconfig/Kconfig work/ch02_warn_depends/zephyr/.config请解释为什么CONFIG_LEARN_DEPENDS_CLIENTy没有进入最终配置。练习二给出修复方式以下请求怎样修改才能成立CONFIG_LEARN_REQUIRED_BACKENDn CONFIG_LEARN_DEPENDS_CLIENTy练习三判断问题属于哪一层如果.config已经有CONFIG_USS_PROFILINGy但uss_prof.c不在compile_commands.json中下一步应该检查哪个文件自测题为什么不能只检查prj.confbuild_info.yml和.config分别回答什么问题给无 prompt symbol 赋值为什么是错误的为什么 symbol 最终为 y仍不一定代表某个.c文件已经进入 ELFwarning 后应检查哪三个构建结果来判断是否真的继续下一章第 3 章 Devicetree 与 Binding。