38.驱动调试——printk

printk的用法-mz_linux-ChinaUnix博客

printk函数的用法_wwwlyj123321的博客-CSDN博客_printk

34.Linux-printk分析、使用__FILE__, __FUNCTION__, __LINE__ 调试 - 诺谦 - 博客园

linux驱动——cmdline原理及利用_好习惯成就伟大-CSDN博客_cmdline是什么

linux kernel下输入输出console如何实现_做一个有技术追求的人-CSDN博客_linux如何运行console

printk

驱动调试最常用的是使用printk打印debug信息

printk的输出位置可以由uboot传入的bootargs参数决定:

当uboot的命令行里的“console=tty1”时,表示printk()输出在开发板的LCD屏上

当uboot的命令行里的“console=ttySA0,115200”时,表示printk()输出在串口UART0上,波特率=115200

当uboot的命令行里的“console=tty1 console=ttySA0,115200”时,表示printk()同时输出在串口上,以及开发板的LCD屏上

显然printk(),还是根据命令行参数来调用不同控制台的硬件处理函数

printk()能调用平台输出的原理大致流程:

第一步:uboot中bootargs中的参数之一console=xxx会被 __setup("console=", console_setup);函数调用,最终将控制台的信息放到了console_cmdline[]全局数组中

第二步:驱动入口函数会使用register_console(struct console *console)函数,console结构体中的名字会跟console_cmdline[]全局数组中的信息对比,匹配上就把该结构体注册起来,该结构体指向我们需要用的平台,结构体里有对应的输入输出函数可供使用

第三步:使用printk()的时候,先把打印信息放入缓冲区,再调用release_console_sem();函数,使用注册的console结构中的write函数,让控制台把缓冲区的数据输出给用户。

printk()的打印级别"<0>"至 "<7>"

#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			*/

  printk() 可以这样用:printk(KERN_INFO "Hello, world!\n");。
未指定日志级别的 printk() 采用的默认级别是 DEFAULT_MESSAGE_LOGLEVEL,这个宏在 kernel/printk.c 中被定义为整数 4,即对应KERN_WARNING。

内核日志级别的定义如下


#define MINIMUM_CONSOLE_LOGLEVEL  1   /*可以使用的最小日志级别*/
#define DEFAULT_CONSOLE_LOGLEVEL  7 /*比KERN_DEBUG 更重要的消息都被打印*/
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
 
int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL,/*控制台日志级别,优先级高于该值的消息将在控制台显示*/
/*默认消息日志级别,printk没定义优先级时,打印这个优先级以上的消息*/
DEFAULT_MESSAGE_LOGLEVEL,
/*最小控制台日志级别,控制台日志级别可被设置的最小值(最高优先级)*/
MINIMUM_CONSOLE_LOGLEVEL,
DEFAULT_CONSOLE_LOGLEVEL,/* 默认的控制台日志级别*/
};

使用cat /proc/sys/kernel/printk可以查看当前日志使用的各个打印级别

当default_message_loglevel<DEFAULT_CONSOLE_LOGLEVEL时,printk()才会打印出信息

但无论当前控制台日志级别是何值,即使没有在控制台打印出来,可以通过使用dmesg命令查看日志,不论打不打印,日志都会存放在缓冲区。

日志级别的设置

1.通过修改 /proc/sys/kernel/printk  来更改printk打印级别通过

# echo "1 4 1 7" > /proc/sys/kernel/printk来将console_loglevel设为1,让default_message_loglevel默认值大于console_loglevel 值,不满足打印条件,即可屏蔽打印。

缺点就是内核重启后, /proc/sys/kernel/printk的内容又会恢复初值,等于"7 4 1 7"

2.直接修改内核文件

直接修改_call_console_drivers ()函数(位于kernel\printk.c)里的DEFAULT_CONSOLE_LOGLEVEL或者DEFAULT_MESSAGE_LOGLEVEL,使得DEFAULT_MESSAGE_LOGLEVEL>DEFAULT_CONSOLE_LOGLEVEL就可屏蔽打印信息,要打印反过来即可。

3.修改uboot的bootargs参数,

如将uboot命令行里的“console=ttySA0,115200”改为“loglevel=0 console=ttySA0,115200”,表示设置内核的console_loglevel 值=0

使用printk()进行驱动调试

//#define DBG_PRINTK printk  /*调试时候使用,不调试时注释*/
#define DBG_PRINTK(x...)     /*不调试时候使用,调试时注释,所有DBG_PRINTK就会无效*/
DBG_PRINTK(KERN_DEBUG"%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
//__FILE__:    表示文件路径
//__FUNCTION__: 表示函数名
//__LINE__:    表示代码位于第几行
//KERN_DEBUG:   等于7,表示打印级别为7

把该语句在驱动代码中插入到每行需要调试的地方即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值