zoukankan      html  css  js  c++  java
  • linux kernel log之2. dynamic_debug

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

    一. 开启dynamic debug功能

    要使用dynamic_debug需要在kernel的defconfig中开启

    CONFIG_DEBUG_FS=y
    CONFIG_DYNAMIC_DEBUG=y

    用menuconfig去配置的话如下图:

    二 dynamic debug功能使用

    1. 编译好image后,需要挂载debugfs(不挂载的话将不会创建debugfs,那么/sys/kernel/debug/下是空的)。

    修改etc/fstab文件,追加下面这段字符。

    nodev      /sys/kernel/debug debugfs   defaults    0   0
    

     

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

    那这里可以看到该文件所有用dev_dbg()打印出的讯息。

    那如果不开启CONFIG_DYNAMIC_DEBUG,将不会产生/sys/kernel/debug/dynamic_debug目录, 是不能进行动态打印的。

    开启dynamic debug:

    echo "module cvi_mipi_rx +p" > /sys/kernel/debug/dynamic_debug/control
    ②echo "file cvi_vip_cif.c +p" >/sys/kernel/debug/dynamic_debug/control

    这两种方式都是开dynamic debug,第一种是对模块开启,第二种只对文件开启。下面举一个栗子:

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

     

    反之,关闭dynamic debug:

    echo "module cvi_mipi_rx -p" > /sys/kernel/debug/dynamic_debug/control
    ②echo "file cvi_vip_cif.c -p" >/sys/kernel/debug/dynamic_debug/control

    那除了上面的两种方式还有一种可以只开启某个function:

    echo "func _init_resource +p" > /sys/kernel/debug/dynamic_debug/control

    不过一般不太推荐使用这种做法,因为很多functions都是相同名字但属于不同modules的。

    三 dev_err/dev_info/dev_warn系列函数

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

    其实这些函数族本质上和下面printk.h中的定义也是完全一致的。

    #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__)

    下图是示例,可以看到err级别以下的log没有打印,那么设置printk的控制台级别可以把对应的log输出到console(如何设置printk console level可以看上一篇1. printk & dmesg)。

     

    四 可变参数宏(##__VA_ARGS__)

    ##__VA_ARGS__表示可变参数宏,可以用来传递多个参数,如:

    #define my_dbg(fmt, ...) 
    do {                        
            printf("[%s] [%d] " fmt, __func__, __LINE__, ##__VA_ARGS__);
    } while(0)
    
    char *name = "robin";
    int age = 18;
    my_dbg("this is a test. name:%s, age:%d
    ", name, age);

     结果如下:

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

     

  • 相关阅读:
    node获取请求参数的方法get与post请求
    express框架路由未导出错误:Router.use() requires a middleware function but got a Object
    移动端学习之理解WEB APP、Native APP、Hybrid APP以及React Native/uniapp包括H5、小程序等的区别与共通之处
    微信小程序
    “You may need an appropriate loader to handle this file type”
    vue-cli Cannot find module 'less'
    Node 跨域问题 Access to XMLHttpRequest at 'http://localhost:8080/api/user/login' from origin 'http://localhost:808
    Access denied for user 'root'@'localhost' (using password: YES)
    nrm : 无法加载文件 C:Users......因为在此系统上禁止运行脚本。
    继承树追溯
  • 原文地址:https://www.cnblogs.com/fuzidage/p/14785734.html
Copyright © 2011-2022 走看看