支持作者新书,点击低折扣购买《Yocto项目实战教程:高效定制嵌入式Linux系统》
ftrace 实战调试:使用 ftrace 精准追踪 I2C 设备驱动 probe 函数
本文以 NXP i.MX8MP-EVK 开发板为平台,使用设备树中实际存在的 I2C 芯片
pca9450
(位于 i2c1@0x25)为例,手把手讲解如何用 ftrace 验证驱动是否成功进入 probe() 函数,识别设备树配置是否生效。这是实际嵌入式开发项目中常见而且必要的调试方式。
一、调试目标:验证 PCA9450 是否被正确驱动
在实际项目中,I2C 类设备常通过设备树进行注册,由内核的 i2c-core 框架统一处理匹配并触发驱动注册。我们需要验证以下三件事:
pca9450
的设备树节点是否被内核正确识别;pca9450
驱动的probe()
函数是否被调用;- probe() 函数中注册的
regulator
是否生效;
设备树中对应的片段如下(来自实际 imx8mp-evk 设备树):
二、配置 ftrace 环境(仅需一次)
内核配置要求
在内核中启用以下配置(通过 make menuconfig
):
CONFIG_FUNCTION_TRACER=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
这些配置均位于:Kernel hacking
→ Tracers
→ 勾选 function
, function_graph
,并启用 syscall tracing。
开发板运行时准备
# 仅首次运行或未挂载时执行:
mount -t debugfs none /sys/kernel/debug
验证:
cat /sys/kernel/debug/tracing/available_tracers
应输出包括:function
, function_graph
, nop
等。
三、使用 ftrace 追踪 pca9450_probe()
步骤 1:切换 tracer 模式为函数追踪
echo function > /sys/kernel/debug/tracing/current_tracer
步骤 2:设定追踪目标函数名
echo pca9450_probe > /sys/kernel/debug/tracing/set_ftrace_filter
如果你想观察 probe 内部的更多细节,可追加:
echo regulator_register > /sys/kernel/debug/tracing/set_ftrace_filter
或追踪多个函数:
echo 'pca9450_probe:regulator_register:devm_regulator_register' > /sys/kernel/debug/tracing/set_ftrace_filter
步骤 3:开启追踪
echo 1 > /sys/kernel/debug/tracing/tracing_on
步骤 4:触发 probe —— 最常见做法是重启开发板
reboot
你也可以使用以下方式手动重新加载驱动:
echo -n 0x25 > /sys/bus/i2c/devices/i2c-1/delete_device
echo nxp,pca9450c 0x25 > /sys/bus/i2c/devices/i2c-1/new_device
(此方式要求 i2c-core 动态设备注册支持)
四、查看追踪结果并判断 probe 是否执行
方法 1:快速 grep
cat /sys/kernel/debug/tracing/trace | grep pca9450_probe
方法 2:查看完整调用链(推荐)
cat /sys/kernel/debug/tracing/trace
示例输出:
kworker/0:2-73 [000] .... 8.934567: pca9450_probe+0x0/0x1d0 <- i2c_device_probe
说明:
pca9450_probe()
函数已被成功调用;- 被
i2c_device_probe()
间接触发,说明设备树匹配成功; - 驱动已被绑定并执行初始化流程;
若完全无输出,可能原因包括:
- compatible 字符串不匹配(驱动中声明为
"nxp,pca9450"
而设备树中写成"nxp,pca9450c"
) - reg 地址错误(0x25 实际硬件地址不对)
- I2C 总线未接好或被禁用(如 i2c1 节点 status = “disabled”)
- 驱动未编入内核或未自动加载
五、关闭 ftrace,清理追踪状态
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo nop > /sys/kernel/debug/tracing/current_tracer
echo > /sys/kernel/debug/tracing/set_ftrace_filter
建议同时清空旧日志:
echo > /sys/kernel/debug/tracing/trace
六、进一步扩展调试建议
调试 regulator 是否注册成功
可继续追踪以下函数:
regulator_register
devm_regulator_register
of_regulator_register
示例:
echo 'regulator_register:devm_regulator_register' > /sys/kernel/debug/tracing/set_ftrace_filter
然后重启或热插模块,查看是否触发。
限定只追踪某一进程(可选)
echo <pid> > /sys/kernel/debug/tracing/set_ftrace_pid
七、实战调试场景总结
目标 | ftrace 是否适用 | 常用方法 |
---|---|---|
驱动是否匹配设备树? | ✅ 是 | 追踪 probe 函数是否调用 |
regulator 子节点是否生效? | ✅ 是 | 追踪 regulator_register 系列函数 |
dmesg 没有日志怎么办? | ✅ 可替代 | 查看 trace 内容而非 printk |
判断 probe 调用先后顺序 | ✅ 很适合 | 使用 function_graph 分析时序 |
八、总结
通过 ftrace,我们可以无需任何 printk 修改,就能实时、精确地判断 I2C 设备的驱动绑定、probe 调用流程与后续资源注册行为是否成功。
本篇以 pca9450
为实际例子,在 i.MX8MP-EVK 平台下,通过设备树绑定 + ftrace 追踪,构建了真实有效的调试路径。
未来你也可以将此调试方式扩展至:
- camera sensor(如 ov5640)
- 音频 codec(如 wm8960)
- I2C IO 扩展芯片(如 pca6416)等所有 I2C 外设场景。