1 dynamic_debug介绍#

这里强烈推荐驱动开发者用这种方式输出log。linux kernel space中有pr_debug及dev_dbg来使用dynamic debug。可以看到当用户define DEBUG后,pr_debug和dev_dbg就等于printk的KERN_DEBUG级别输出了;否则什么也不打印。

1.1 开启dynamic debug#
要使用dynamic_debug需要在kernel的defconfig中开启。
1 | CONFIG_DEBUG_FS=y |
用menuconfig去配置的话如下图:

1.2 dynamic debug使用#
编译好image后,需要挂载debugfs(不挂载的话将不会创建debugfs,那么/sys/kernel/debug/下是空的)。
修改etc/fstab文件,追加下面这段字符:
1 | nodev /sys/kernel/debug debugfs defaults 0 0 |

可以用cat /sys/kernel/debug/dynamic_debug/control | grep xxx.c来查看自己想要查看的log所在文件有没有包含进去。

这里可以看到该文件所有用dev_dbg()打印出的讯息。
那如果不开启CONFIG_DYNAMIC_DEBUG,将不会产生/sys/kernel/debug/dynamic_debug目录, 是不能进行动态打印的。
1.2.1 开启dynamic debug#
1 | echo "module cvi_mipi_rx +p" > /sys/kernel/debug/dynamic_debug/control |
这两种方式都是开dynamic debug,第一种是对模块开启,第二种只对文件开启。
下面举一个栗子:

开启之后,可以看到dev_dbg()打印的log都会输出。

反之,关闭dynamic debug:
1 | echo "module cvi_mipi_rx -p" > /sys/kernel/debug/dynamic_debug/control |
除了上面的两种方式还有一种可以只开启某个function:
1 | echo "func _init_resource +p" > /sys/kernel/debug/dynamic_debug/control |

2 dev_err/dev_info/dev_warn#
在Linux驱动代码中,有大量的调试信息,那么推荐使用dev_err/dev_info/dev_warn这一系列函数族。这一系列函数族定义在include/linux/device.h。

其实这些函数族本质上和下面printk.h中的定义也是完全一致的。
1 |
下图是示例,可以看到err级别以下的log没有打印,那么设置printk的控制台级别可以把对应的log输出到console。

如何设置printk console level可以看上一篇Linux日志管理-printk和dmesg。
3 可变参数宏#
##__VA_ARGS__表示可变参数宏,可以用来传递多个参数,如:
1 |
|
结果如下:

那和下面这种写法呢本质上是完全一样的。

4 模块打印等级控制#
4.1 按照打印等级控制#
1 |
|
当级别高于DBG,即可输出高于DBG的所有级别打印。
4.2 精确控制打印等级#
1 | extern u32 vi_log_lv; |
可以随意开启任意级别打印,比如只开启DBG,只开启WARN。
5 用户态模块打印等级控制#
1 | XXX_S32 *log_levels; |