转自:http://www.360doc.com/content/12/0225/15/8204997_189530723.shtml
一、在驱动开发中,效率很重要。
1.锁的选用
a)免锁算法 >> 细颗粒的锁 >> 粗颗粒的锁。
b)中断与轮询
通常情况下,中断方式比轮询更有效率。但如果数据量非常非常大,一个数据没有处理完,下一次数据又来了,这样的情况下轮询会比中断有效率, 因为
1.轮询可以省略下中断触发时,硬件切换和中断切换的时间,
2. 可以减小系统对输入输出的响应,让系统有时间可以处理输入输出。
c) 是否需要create_workqueue_thread()
内核中有workqueque的处理线程,是否需要单独建立一个。
如果数据量不大,多余的workqueue_thread会影响内核的性能。因为,会多一些thread切换的开销
二、调试接口
在软件开发中,调试永远占着非常重要的地位。毕竟人脑没法按照CPU的方式工作。
1.合理的控制自己的消息打印
消息打印是最原始的调试方式,也是最有用的调试方式。合理的控制自己的打印信息,绝对能事半功倍。
a) release 版本和debug版本
添加宏开关,控制打印信息是否编译。在 release版本中不包含打印信息
b)通过module_param_named()控制打印等级,从而控制打印是否输出
在/sys/module下面的模块里,给内核中驱动模块留下了这个接口,可以很方便的控制输出等级。
static int msm_pm_debug_mask;
module_param_named(
debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
);
#define MSM_PM_DPRINTK(mask, level, message, ...) \
do { \
if ((mask) & msm_pm_debug_mask) \
printk(level message, ## __VA_ARGS__); \
} while (0)
2. 内核模块中的打印信息
内核模块中留有丰富的调试接口。
a) debugfs
在代码中看到了
debugfs_create_dir()
debugfs_create_u32()
恭喜你,前人已栽好树,找个地方乘凉去吧。搞清楚目录位置,到处相应的数据,分析去吧。
b)CONFIG_DYNAMIC_PRINTK_DEBUG
这是一个开关,通过这一开关,可以打开内核中的一些打印信息。
请参考
kernel/Documentation/dynamic-debug-howto.txt
c) proc
其实/proc下也有很多内核导出的信息。
/proc/meminfo
/proc/cpuinfo
/proc/cmdline --kernel启动参数
/proc/task/ ---列出了系统当前的进程,以及进程的很多信息。
三、分析工具
1. dump_stack()
很方便的打印出当前函数的调用堆栈的函数。使用非常方便,分析内核里的framework非常方便。
2. 找出image中编译的了那个函数。
经常遇到一个函数在多个文件中都有实现,分析很久才能搞清楚到底是哪一个函数。有了下面这个工具,就可以很轻松的知道是哪一个工具了。
arm-eabi-nm -A -a -l -n
vmlinux | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' >
System.map
这个工具对HAL层的动态库同样有用
3.
有时候,看到kernel里面上万个文件和各种各样的宏,是不是很有干掉一些的冲动?推荐看看stripcc
4. .config
kernel里面的Kconfig也是一绝,我经常搞不清楚到底那么错综复杂的依赖关系。不过还好,.config。
这个文件在输出目录下,是kernel编译时,各种CONFIG的配置结果。
所以,如果不确定编译开关是否打开,检查一下这个文件即可。