前面两节我们介绍了printk的基本原理和printk在驱动调试中的用法,现在我们看一下printk的继任者,pr_xxx系列函数
可以看到,如果没有定义pr_fmt(fmt),那么pr_fmt(fmt)就是fmt,这样的话pr_xxx系列函数仅仅是一个printk的简单封装
但是精髓在于可以自己定义pr_fmt(fmt),让我们封装成自己的打印函数,方便调试
... ...
#ifndef pr_fmt
#define pr_fmt(fmt) fmt
#endif
/*
* These can be used to print at the various log levels.
* All of these will print unconditionally, although note that pr_debug()
* and other debug macros are compiled out unless either DEBUG is defined
* or CONFIG_DYNAMIC_DEBUG is set.
*/
#define pr_emerg(fmt, ...) \
printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
#define pr_alert(fmt, ...) \
printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_crit(fmt, ...) \
printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_err(fmt, ...) \
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warning(fmt, ...) \
printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warn pr_warning
#define pr_notice(fmt, ...) \
printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
#define pr_info(fmt, ...) \
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
... ...
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
可以给用户要输出的log前面添加额外的固定的信息,方便调试
下面给出参考博客中的一些用法:(自己的宏定义要写在文件的第一行定义pr_fmt)
/*
* #define pr_fmt(fmt) "gpio_demo: " fmt
* #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
* #define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__
*/
#include xxx
... ...
static int gpio_demo_probe(struct platform_device *pdev) {
... ...
pr_info("%s enter.\n", __func__);
... ...
}
下面是 #define pr_fmt(fmt) "gpio_demo: " fmt 的输出:
[ 1022.623230] gpio_demo: gpio_demo_probe enter.
下面是 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 的输出(KBUILD_MODNAME是模块的名字,可以阅读这个驱动文件的Makefile文件获得):
[ 1088.639631] gpio_demo: gpio_demo_probe enter.
下面是 #define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__ 的输出:
[ 1135.108534] gpio_demo:gpio_demo_probe:87: gpio_demo_probe enter.
当然,也不一定非得在文件的第一行进行宏定义,也可以在需要的地方:
#undef pr_fmt(fmt)移除宏定义,然后再自行定义
参考博客:https://www.cnblogs.com/pengdonglin137/p/6209424.html