五、【打印信息】驱动程序中的打印信息级别介绍
打开kernel源码可见有以下几个宏:
1 2 3 4 5 6 7 8 | #define KERN_EMERG "<0>" /* system is unusable */ #define KERN_ALERT "<1>" /* action must be taken immediately */ #define KERN_CRIT "<2>" /* critical conditions */ #define KERN_ERR "<3>" /* error conditions */ #define KERN_WARNING "<4>" /* warning conditions */ #define KERN_NOTICE "<5>" /* normal but significant condition */ #define KERN_INFO "<6>" /* informational */ #define KERN_DEBUG "<7>" /* debug-level messages */ |
级别从0~7,数字越小,级别越高。
查看系统printk的打印级别:
这四个数字代表下面数组的值:
1 2 3 4 5 6 | int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ }; |
7——控制台日志信息级别,只有级别比该级别高的信息才会打印显示
7——默认的消息日志信息级别(如果信息级别没指定,默认是该级别)printk("xxx_init\n");
1——控制台日志信息所能设置的最小数字(最高级别)
7——默认的控制台日志信息级别。
举例:我在驱动程序中加了printk信息,但是执行可执行程序调到时没有输出打印信息。
(1)驱动程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/ioport.h> #include <linux/io.h> #include <linux/uaccess.h> static struct cdev led; static dev_t dev; static struct class *led_cls=NULL; static int led_open( struct inode* inode, struct file *filp) { printk( "led_open\n" ); return 0; } static int led_close( struct inode* inode, struct file *filp) { printk( "led_close\n" ); return 0; } static ssize_t led_write( struct file *filp, const char __user *user, size_t size, loff_t *oft) { printk( "led_write\n" ); return size; } struct file_operations fops= { .open = led_open, .release = led_close, .write = led_write, }; static int __init led_init( void ) { printk( "led_init\n" ); led.owner = THIS_MODULE; cdev_init(&led,&fops); alloc_chrdev_region(&dev, 0, 1, "led_chrdev" ); cdev_add(&led, dev, 1); led_cls = class_create(THIS_MODULE, "led_class" ); device_create(led_cls, NULL,dev, NULL, "led_dev" ); return 0; } static void __exit led_exit( void ) { printk( "xxxx__exit\n" ); device_destroy(led_cls , dev); class_destroy(led_cls); cdev_del(&led); } module_init(led_init); module_exit(led_exit); MODULE_AUTHOR( "yqf" ); MODULE_DESCRIPTION( "led driver program" ); MODULE_LICENSE( "GPL" ); |
(2)应用程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { int fd; char buff[2]={0}; fd = open( "/dev/led_dev" ,O_RDWR); if (fd<0) { perror ( "open led_dev error!" ); } write(fd,buff, sizeof (buff)/ sizeof (buff[0])); close(fd); } |
理论上我驱动程序的open、write、close都有printk打印信息,main.c中有去调用驱动程序中的这几个函数,但是没有打印信息。
解决方法一:
由上面的打印信息级别可知,现在默认的消息日志级别为7,只有比控制台日志的级别高才可以打印出信息,所以将消息日志的级别设置得比7小即可输出信息。
解决方法二:
在驱动程序中加打印级别:
1 | printk(KERN_INFO "led_open\n" ); |
1 | KERN_INFO的值 "<6>" ,比控制台级别7级别高,所以不用修改prink文件,就可以输出打印信息。 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)