对于复杂的linux驱动及HAL等程序库,需要使用各种方法对其进行调试,例如设置断点、逐步跟踪代码,输出调试信息等。
一、打印内核调试信息:printk
该函数用法与printf函数类似,只不过printk函数运行在linux内核空间,而printf函数在用户空间。
例如:printk(“hello world ”);
Printk(“hello %s ”,”world”);
Printk(KERN_DEBUG”debug information ”);或Printk(<7>”debug information ”);
在printk函数的第一个参数值前面加尖括号包含的数字表示输出的日志级别。Printk文件是一个简单的有4个数字组成的文本文件,该文件的默认值有:
6:将消息输出到控制台的级别
4:默认的消息日志级别
1:控制台日志级别可被设置的最小值,最高优先级
7:控制台默认级别的默认值
二、防止printk函数降低linux驱动性能
虽然输入printk函数可以很方便的将消息写入日志文件或控制台,但大量的printk函数频繁操作日志文件或控制台设备文件会严重影响linux驱动的性能。Linux驱动在测试阶段可以使用printk函数,但发布时就需要把printk函数去掉,这就需要利用c语言的编译指令(#if,#else,#endif等)。
1.可变参数宏
可变参数宏和固定参数宏的不同之处就是可变参数宏需要通过_VA_ARGS_宏获取可变参数宏的可变参数。
2.do{…}while(0)循环体执行一次就退出,就是将多条作为一个整体处理。
三、通过文件虚拟系统(/proc)进行数据交互
/proc并不是真正的文件系统而是内存映射,所有读写/proc的操作都是对内存的读写,/proc文件可以成为linux驱动与用户空间程序交互的工具。在Linux 驱动程序中可以使用内核函数在/proc 目录中创建和删除虚拟文件,也可以建立和删除虚拟目录。
四个函数:1. proc_mkdir 建立虚拟目录
2.create_proc_entry 建立虚拟文件
3. create_proc_read_entry 建立虚拟只读文件
4. remove_proc_entry 删除虚拟文件或目录
四、调试工具
这些工具包括用于调试用户空间程序的gdb,gdbserver以及内核空间程序的kgdb。通过这些工具可以逐行跟踪程序的代码。
(1)gdb和gdbserver常用的调试命令:
list:用于列出程序中的代码
break n :将指定行设置为断点,n表示行号
clear n:清除指定行的断点
tbreak n:将指定行设置为断点
run:运行程序
cont/continue:跳过当前断点继续执行
next:继续执行下面的语句 nexti:单步执行语句
print var_name:查看变量值
(2)kgdb远程调试内核程序
kgdb提供了类似printk函数的日志输出功能,还允许开发人员直接在PC上通过GDB链接目标设备。Kgdb包含了两部分:kgdb内核和一套连接接口。这些接口目前支持串口tty设备连接和以太网连接。最后再按要求配置linux内核即可。