在驱动开发的早期, 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. spark在collect收集数据的时候出现outOfMemoryError:java heap space

    spark的collect是action算子,所有最后会以数组的形式返回给driver端,当数据太大的时候就会出现堆内存溢出.OutofMemoryError:java heap space. 在sp ...

  2. NX二次开发-UFUN更改图纸页比例UF_DRAW_set_drawing_info

    #include <uf.h> #include <uf_draw.h> #include <uf_part.h> UF_initialize(); //获得当前图 ...

  3. Java-Class-@I:org.springframework.beans.factory.annotation.Autowired

    ylbtech-Java-Class-@I:org.springframework.beans.factory.annotation.Autowired 1.返回顶部   2.返回顶部 1. pack ...

  4. tomcat部署项目报错NoSuchMethodException#addServlet,addFilter

    java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet java.lang.NoSuchMethod ...

  5. sizeof,真正终结版GCC与VC

    在VC6.0中sizeof结果是16.我电脑上装了个linux虚拟机,在虚拟机上GCC中结果是12, 恩不同编译器默认对齐数值不一样. VC 默认为 8 gcc 默认为 4 有个编译参数控制对齐. # ...

  6. (转)python常用模块(模块和包的解释,time模块,sys模块,random模块,os模块,json和pickle序列化模块)

    阅读目录 1.1.1导入模块 1.1.2__name__ 1.1模块 什么是模块: 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代 ...

  7. linux 下 CDH4.5编译

    1.安装JDK JDK:我这里 安装的是jdk1.6.0_23 1.1:给文件执行的权限chmod u+x jdk-6u23-linux-x64.bin 1.2: ./jdk-6u23-linux-x ...

  8. 唯一id

    package com.debug.kill.server.utils; /** * Created by Administrator on 2019/6/20. */ import org.apac ...

  9. 从零开始:Mysql基于Amoeba的集群搭建

    从零开始:Mysql基于Amoeba的集群搭建 准备环境 1.mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz 2.amoeba-mysql-binary-2.0. ...

  10. 【JZOJ6389】小w学图论

    description 小w这学期选了门图论课,他在学习点着色的知识.他现在得到了一张无向图,并希望在这张图上使用最多n种颜色给每个节点染色,使得任意一条边关联的两个节点颜色不同. 小w获得一张n个节 ...