在驱动开发的早期, printk 非常有助于调试和测试新代码. 当你正式发行驱动时, 换句 话说, 你应当去掉, 或者至少关闭, 这些打印语句. 不幸的是, 你很可能会发现, 就在你 认为你不再需要这些消息并去掉它们时, 你要在驱动中实现一个新特性(或者有人发现了 一个 bug), 你想要至少再打开一个消息. 有几个方法来解决这 2 个问题, 全局性地打开 或关闭你地调试消息和打开或关闭单个消息.

这里我们展示一种编码 printk 调用的方法, 你可以单独或全局地打开或关闭它们; 这个 技术依靠定义一个宏, 在你想使用它时就转变成一个 printk (或者 printf)调用.

  • 每个 printk 语句可以打开或关闭, 通过去除或添加单个字符到宏定义的名子.
  • 所有消息可以马上关闭, 通过在编译前改变 CFLAGS 变量的值.
    • 同一个 print 语句可以在内核代码和用户级代码中使用, 因此对于格外的消息, 驱动和测试程序能以同样的方式被管理.

下面的代码片断实现了这些特性, 直接来自头文件 scull.h:

#undef PDEBUG /* undef it, just in case */

#ifdef SCULL_DEBUG

# ifdef  KERNEL

/* This one if debugging is on, and kernel space */

# define PDEBUG(fmt, args...) printk( KERN_DEBUG "scull: " fmt, ## args)

# else

/* This one for user space */

# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)

# endif

#else

# define PDEBUG(fmt, args...) /* not debugging: nothing */

#endif

#undef PDEBUGG #define PDEBUGG(fmt, args...)        /* nothing: it's a placeholder */

符号 PDEBUG 定义和去定义, 取决于 SCULL_DEBUG 是否定义, 和以何种方式显示消息适 合代码运行的环境: 当它在内核中就使用内核调用 printk, 在用户空间运行就使用 libc 调用 fprintf 到标准错误输出. PDEBUGG 符号, 换句话说, 什么不作; 他可用来轻易地" 注释" print 语句, 而不用完全去掉它们.

为进一步简化过程, 添加下面的行到你的 makfile 里:

# Comment/uncomment the following line to disable/enable debugging DEBUG = y

# Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y)

DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines else

DEBFLAGS = -O2

endif

CFLAGS += $(DEBFLAGS)

本节中出现的宏定义依赖 gcc 对 ANSI C 预处理器的扩展, 支持带可变个数参数的宏定 义. 这个 gcc 依赖不应该是个问题, 因为无论如何内核固有的非常依赖于 gcc 特性. 另 外, makefile 依赖 GNU 版本的 make; 再一次, 内核也依赖 GNU make, 所以这个依赖不 是问题.

如果你熟悉 C 预处理器, 你可以扩展给定的定义来实现一个"调试级别"的概念, 定义不 同的级别, 安排一个整数(或者位掩码)值给每个级别, 以便决定它应当多么详细.

但是每个驱动有它自己的特性和监视需求. 好的编程技巧是在灵活性和效率之间选择最好 的平衡, 我们无法告诉你什么是最好的. 记住, 预处理器条件(连同代码中的常数表达式) 在编译时执行, 因此你必须重新编译来打开或改变消息. 一个可能的选择是使用 C 条件 句, 它在运行时执行, 因而, 能允许你在出现执行时打开或改变消息机制. 这是一个好的 特性, 但是它在每次代码执行时需要额外的处理, 这样即便消息给关闭了也会影响效率. 有时这个效率损失无法接受.

本节出现的宏定义已经证明在多种情况下是有用的, 唯一的缺点是要求在任何对它的消息 改变后重新编译.

printk函数打开和关闭消息的更多相关文章

  1. VB Open 函数详解 打开、关闭、读、写文件

    (一)打开和关闭文件      1.顺序文件     打开顺序文件,我们可以使用Open语句.它的格式如下:Open pathname For [Input |Output |Append] As [ ...

  2. printk 函数消息是如何记录的

    printk 函数将消息写入一个   LOG_BUF_LEN 字节长的环形缓存, 长度值从 4 KB 到 1 MB, 由配置内核时选择. 这个函数接着唤醒任何在等待消息的进程, 就是说, 任何在系统 ...

  3. liunx printk 函数消息是如何记录的

    printk 函数将消息写入一个   LOG_BUF_LEN 字节长的环形缓存, 长度值从 4 KB 到 1 MB, 由配置内核时选择. 这个函数接着唤醒任何在等待消息的进程, 就是说, 任何在系统 ...

  4. RMS Server打开或关闭日志记录

    原文: https://technet.microsoft.com/zh-cn/library/cc732758 在 Active Directory Rights Management Servic ...

  5. printk函数日志级别的设置【转】

    本文转载自: 下面执行cat /proc/sys/kernel/printk 打印出的四个数字分别代表: 控制台日志级别.默认的消息日志级别.最低的控制台日志级别和默认的控制台日志级别 只有当prin ...

  6. C++学习47 文件的概念 文件流类与文件流对象 文件的打开与关闭

    迄今为止,我们讨论的输入输出是以系统指定的标准设备(输入设备为键盘,输出设备为显示器)为对象的.在实际应用中,常以磁盘文件作为对象.即从磁盘文件读取数据,将数据输出到磁盘文件.磁盘是计算机的外部存储器 ...

  7. Linux C 文件与目录2 文件的打开与关闭

    文件的打开与关闭 open和close 文件的打开指的是从磁盘中找到一个文件,返回一个整形的打开文件顺序的编号.打开的文件处于可读.可写状态.文件的关闭指的是释放打开的文件,是文件处于不可读写的状态. ...

  8. Linux C编程--打开和关闭流

    以下函数用于打开和关闭一个流.#include <stdio.h>FILE * fopen (const char *pathname, const char *opentype);int ...

  9. 标准I/O库之打开和关闭流

    下列三个函数打开一个标准I/O流. #include <stdio.h> FILE *fopen( const char *restrict pathname, const char *r ...

随机推荐

  1. NX二次开发-设置WCS位置UF_CSYS_set_wcs

    NX9+VS2012 UF_initialize(); //输入X向量Y向量输出一个3*3矩阵 ] = {0.0, 0.0, 1.0}; ] = {0.0, 1.0, 0.0}; ]; UF_MTX3 ...

  2. NX二次开发-NXOPEN创建工程图表格Annotations::TableSectionBuilder *tableSectionBuilder1;

    NX9+VS2012 #include <uf.h> #include <uf_tabnot.h> #include <NXOpen/Part.hxx> #incl ...

  3. C++源文件的后缀名问题

    VC里用cpp作后缀名, 在GCC里默认采用C.cc.cxx作为后缀名 .cpp, .h (VS file).cc, .h (GCC file)   C中: 头文件后缀名: .h 源文件后缀名: .c ...

  4. Api:目录

    ylbtech-Api:目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.c ...

  5. Python 数据结构_队列

    目录 目录 队列 队列 Queue 队列是一种先进先出(FIFO)的数据类型, 新的元素通过 入队 的方式添加进 Queue 的末尾, 出队 就是从 Queue 的头部删除元素. 用列表来做 Queu ...

  6. Codeforces 1174B Ehab Is an Odd Person

    题目链接:http://codeforces.com/problemset/problem/1174/B 题意:给定长度 n 的数组,任意俩个相加为奇数的数可以交换数组中的位置,让这个数组尽量从小到大 ...

  7. 来个我一起学习Python把!!!(新手共同努力)

    <初识Python> 大家好,让我们一起来学习Python,因本人也是个新手但我会把我所学的东西分享出来,并记录自己的经验学习过程,不单单是分享代码,会详细的讲解,如有错误地方希望大家指点 ...

  8. python 17 函数基础(一)

    http://www.cnblogs.com/BeginMan/p/3171977.html 一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/arch ...

  9. Ubuntu升级软件和ubuntu升级系统的命令

    sudo apt-get update: 升级安装包相关的命令,刷新可安装的软件列表(但是不做任何实际的安装动作) sudo apt-get upgrade: 进行安装包的更新(软件版本的升级) su ...

  10. C++ 系列:随机数

    C++中没有自带的random函数,要实现随机数的生成就需要使用rand()和srand().不过,由于rand()的内部实现是用线性同余法做的,所以生成的并不是真正的随机数,而是在一定范围内可看为随 ...