您尚未登录。

楼主 # 2022-01-22 22:47:05

cwd502
会员
注册时间: 2021-12-25
已发帖子: 5
积分: 2

Linux内核驱动各种debug汇总

1.printk
(1)printk打印等级类型如下:
printk(KERN_DEBUG "hello"); //
#define KERN_EMERG KERN_SOH "0" / system is unusable /
#define KERN_ALERT KERN_SOH "1" / action must be taken immediately /
#define KERN_CRIT KERN_SOH "2" / critical conditions /
#define KERN_ERR KERN_SOH "3" / error conditions /
#define KERN_WARNING KERN_SOH "4" / warning conditions /
#define KERN_NOTICE KERN_SOH "5" / normal but significant condition /
#define KERN_INFO KERN_SOH "6" / informational /
#define KERN_DEBUG KERN_SOH "7" / debug-level messages /
(2)printk开启打印
使用:
cat /proc/sys/kernel/printk
7    4    1    7 4(新版Linux才有)
echo 8 > /proc/sys/kernel/printk //8 > KERN_DEBUG, so KERN_DEBUG will print
分析:
kernel/printk/prink.c有如下定义:
int console_printk[5] = {
CONSOLE_LOGLEVEL_DEFAULT, /7,console_loglevel, 控制台输出,<7 的才输出 /
MESSAGE_LOGLEVEL_DEFAULT, /6,default_message_loglevel, 即printk(“hell world”);优先级为4 /
CONSOLE_LOGLEVEL_MIN, /1,minimum_console_loglevel, 最小支持的打印等级为1,0留给内核严重错误使用 /
CONSOLE_LOGLEVEL_DEFAULT, /7,default_console_loglevel, 第一个默认的等级/
MESSAGE_LOGLEVEL_DEFAULT, /4,default_devkmsg_loglevel, 进入kmesg /dev/kmsg log的等级/
};
(1)第一个参数7:表示小于7优先级消息才会被输出到控制台。
(2)第二个参数4 :表示默认的printk消息优先级别,即printk(“hell world”);优先级为4, 由于4<7,故可以被打印到控制台。
(3)第三个参数1 :表示可接收的最高优先级,当printk disable控制台输出时,设置第一个参数为1,但是,从内核等级来看,还有优先级0,这个是printk最高级优先级,一般用于内核严重消息打印。比如内存错误或者 watchdog reset.也可以设置第一个和第三个参数为0
(4)第四个参数7: 默认控制台优先级,即第一个参数的默认优先级。
(5)第五个参数4:执行dmesg(/dev/kmsg)输出log,该等级即是消息进入log的等级,<4 的消息都能在dmesg下找到。

  1. dev_dbg、 pr_debug、dev_vdbg、dev_printk
    dev_dbg定义:
    #if defined(CONFIG_DYNAMIC_DEBUG) //如果定义动态调试,执行echo 'file hub.c +p' > /sys/kernel/debug/dynamic_debug/control 开启打印
    #define dev_dbg(dev, format, ...) \
    do { \
    dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
    } while (0)
    #elif defined(DEBUG) //定义了debug,则 dev_printk(KERN_DEBUG""), 执行 echo 8 > /proc/sys/kernel/printk 开启打印
    #define dev_dbg(dev, format, arg...) \
    dev_printk(KERN_DEBUG, dev, format, ##arg)
    #else //不打印
    #define dev_dbg(dev, format, arg...) \
    ({ \
    if (0) \
    dev_printk(KERN_DEBUG, dev, format, ##arg); \
    })
    #endif
    pr_debug定义:
    / If you are writing a driver, please use dev_dbg instead /
    #if defined(CONFIG_DYNAMIC_DEBUG)
    #include <linux/dynamic_debug.h>

/ dynamic_pr_debug() uses pr_fmt() internally so we don't need it here /
#define pr_debug(fmt, ...) \
dynamic_pr_debug(fmt, ##__VA_ARGS__) //动态调试
#elif defined(DEBUG)
#define pr_debug(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) //正常打印
#else
#define pr_debug(fmt, ...) \
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) //不打印
#endif
dev_vdbg定义:
#ifdef VERBOSE_DEBUG //定义了这个才打印
#define dev_vdbg dev_dbg
#else
#define dev_vdbg(dev, format, arg...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, format, ##arg); \
})
#endif

dev_printk定义:
static void __dev_printk(const char level, const struct device dev,
struct va_format *vaf)
{
if (dev) //带个前缀
dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", dev_driver_string(dev), dev_name(dev), vaf);
else
printk("%s(NULL device *): %pV", level, vaf);
}
void dev_printk(const char level, const struct device dev,
const char *fmt, ...)
{
struct va_format vaf;
va_list args;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
__dev_printk(level, dev, &vaf);
va_end(args);
}
EXPORT_SYMBOL(dev_printk);

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn


东莞哇酷科技有限公司开发