少于 1 分钟阅读 次阅读

概要:本文介绍了在驱动开发过程中,通过使用打印日志的技巧进行调试的方法,包括在关键函数中添加日志、使用宏和特殊标记进行定位与检索,并补充了与 __FUNCTION__ 类似的常用宏,提升日志定位能力。

1. 确认驱动加载流程

在驱动开发中,首先要确认是否成功进入了驱动的加载函数(如 probe 函数)。可以在 probe 函数开始时添加日志,确认流程是否按预期执行。

printk("[Witheart] Entering probe function\n");

2. 使用宏增强日志定位能力

为了方便在源码中快速定位日志对应的打印位置,可以使用一些内置宏,例如:

2.1 __FUNCTION__

输出当前所在的函数名称。

printk("Function: %s\n", __FUNCTION__);

输出示例:

Function: phy_rtl8211f_led_fixup

2.2 其他常用调试宏

宏名 含义说明 示例输出
__FILE__ 当前源文件名 main.c
__LINE__ 当前代码所在的行号 42
__func__ C99 标准定义的函数名,与 __FUNCTION__ 类似 phy_rtl8211f_led_fixup
__PRETTY_FUNCTION__ GCC 扩展,显示函数原型,适合 C++ void ClassName::method(int)

2.3 宏组合示例

可以组合多个宏,输出更完整的调试信息:

printk("[Witheart] %s:%s():%d\n", __FILE__, __FUNCTION__, __LINE__);

输出示例:

[Witheart] stmmac_main.c:phy_rtl8211f_led_fixup():1285

3. 使用特殊标记便于检索日志

在日志中加入特定的标识(如 [Witheart]),有助于在海量日志中快速筛选出自己关心的输出内容。这样可以与系统其他日志进行区分,尤其在调试时序问题时尤为重要。


4. 常用形式

printk("[witheart] %s: 日志内容  ==%s\n", __func__, __FILE__);

5. 实际案例:调试 eth 初始化读取 MAC 失败

4.1 背景

笔者在调试以太网(eth)初始化过程中,发现从 EEPROM 中读取 MAC 地址始终失败。

4.2 调试步骤

为此,在 eth 和 EEPROM 的 probe 函数开始处分别添加了带有特殊标记的日志打印,便于后续分析。

console:/ # dmesg | grep -i "witheart"
[    2.072022] mpp_service mpp-srv: 32d8116903 author: Witheart 2025-06-04 git init
[    2.134954] [witheart] rk_gmac_probe begin..
[    2.135529] witheart: rk_get_eth_addr !!! \x0a
[    2.135531] witheart: at24_mac_read at24_private==null error
[    2.974292] [witheart] AT24_probe begin..
[   15.604223] [Witheart] test eth led ctrl start(kernel-5.10/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c)====== phy_rtl8211f_led_fixup
[   15.604649] [Witheart] test eth led ctrl end====== phy_rtl8211f_led_fixup

4.3 分析结果

从日志可以看出,eth 尝试读取 MAC 地址的时间早于 EEPROM 的 probe 初始化完成时间,这就导致读取失败。因此,通过日志分析可以确认问题是由于驱动加载的顺序不当导致的。

留下评论