Linux驱动开发——pr_fmt的用法
作者:彭东林
邮箱:pengdonglin137@163.com
在阅读kernel代码的时候,总是看到有很多驱动都在第一行定义pr_fmt,闲来没事,分析了一下, 发现,确实挺方便的。下面记录分享一下。
我们知道,在驱动中可以使用dev_dbg来输出log,在输出的log中会有一些额外的信息,如所属的device的name。
而pr_fmt就可以实现这个目的,先看一个用法(drivers/i2c/i2c-core.c):
- #define pr_fmt(fmt) "i2c-core: " fmt
- #include <dt-bindings/i2c/i2c.h>
- #include <asm/uaccess.h>
- #include <linux/acpi.h>
- ... ...
但是在这个文件中并没有看到pr_fmt被使用。然后,猜测应该是被哪个宏使用了,所以我在include下搜索pr_fmt发现:
- include/linux/printk.h:: printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
- include/linux/printk.h:: printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
然后看一下printk.h:
- ... ...
- #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__)
- #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
- ... ...
可以看到,如果驱动中没有定义pr_fmt(fmt),那么,pr_fmt(fmt)就是fmt。
使用pr_fmt的还不少, 这里有几个比较常用的函数: pr_err, pr_info, 如果没有定义CONFIG_DYNAMIC_DEBUG, 那么pr_debug也会使用pr_fmt。
从上面的代码已经看到pr_fmt的作用了吧,就是在用户要输出的log前面添加额外的固定的信息。下面结合gpio_demo.c驱动看一下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__
在gpio_demo.c的第一行定义上面的一种, 然后, 在驱动中调用pr_info, 如:
- static int gpio_demo_probe(struct platform_device *pdev) {
- struct device *dev = &pdev->dev;
- int ret = ;
- int i = ;
- int gpio = -;
- gpio_demo_data_t *data = NULL;
- struct resource *res = NULL;
- u32 config, pud, drv;
- 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.
这对输出log确实比较方便。
完。
Linux驱动开发——pr_fmt的用法的更多相关文章
- 嵌入式Linux驱动开发日记
嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...
- Linux 驱动开发
linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...
- Linux驱动开发必看详解神秘内核(完全转载)
Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html IT168 技术文档]在开始步入L ...
- linux驱动开发流程
嵌入式linux驱动开发流程嵌入式系统中,操作系统是通过各种驱动程序来驾驭硬件设备的.设备驱动程序是操作系统内核和硬件设备之间的接口,它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个 ...
- 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- 【转】linux驱动开发的经典书籍
原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书 ...
- Linux驱动开发 -- 打开dev_dbg()
Linux驱动开发 -- 打开dev_dbg() -- :: 分类: LINUX linux设备驱动调试,我们在内核中看到内核使用dev_dbg来控制输出信息,这个函数的实质是调用printk(KER ...
- Linux驱动开发学习的一些必要步骤
1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ...
- 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
随机推荐
- 【探索】机器指令翻译成 JavaScript
前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...
- C#基础篇 - 正则表达式入门
1.基本概念 正则表达式(Regular Expression)就是用事先定义好的一些特定字符(元字符)或普通字符.及这些字符的组合,组成一个“规则字符串”,这个“规则字符串”用来判断我们给定的字符串 ...
- Android和JavaScript相互调用的方法
转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...
- 46张PPT讲述JVM体系结构、GC算法和调优
本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...
- Angular企业级开发(4)-ngResource和REST介绍
一.RESTful介绍 RESTful维基百科 REST(表征性状态传输,Representational State Transfer)是Roy Fielding博士在2000年他的博士论文中提出来 ...
- 玩转spring boot——AOP与表单验证
AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- 快速了解微信小程序的使用,一个根据小程序的框架开发的todos app
微信官方已经开放微信小程序的官方文档和开发者工具.前两天都是在看相关的新闻来了解小程序该如何开发,这两天官方的文档出来之后,赶紧翻看了几眼,重点了解了一下文档中框架与组件这两个部分,然后根据简易教程, ...
- docker4dotnet #4 使用Azure云存储构建高速 Docker registry
使用Docker来构建应用程序最常见的操作就是 docker run 或者 docker pull了,但是由于众所周知的原因,在国内想要高速稳定的获取docker hub上面的资源并不是件容易的事情, ...
- js实现四大经典排序算法
为了方便测试,这里写了一个创建长度为n的随机数组 function createArr(n) { var arr = []; while (n--) { arr.push(~~(Math.random ...