好久没写东西,也不知道写些什么,就随便说说调试吧。
说的调试,我们难免会想到打印。我想,打印是平时调试程序中用的最多的一种手段。而打印,我们平时一般都不会直接用“printf”,二是用一个宏,如:
#define HALPRINTF printf
// #define HALPRINTF (···)
用可变参数的形式,就可以做到随意的开关调试信息的目的了。
把消息打印到内核,然后就可以在/proc/kmsg中查看HAL层的打印消息了。在这里要做一个简单的驱动:
KernelWrite(···)
{
···
Printk(···);
···
}
.write = KernelWrite,
然后在HAL中打开并调用:
fd = open(XX.ko,···);
HalWrite(···)
{
Write(fd,···);
}
#define HALPRINTF HalWrite
#define HALPRINTF(···)
这样子就把用户空间的消息打印到了内核中,然后 cat /proc/kmsg 就可以把消息显示在终端。
用logcat打印。Logcat是android自带的调试工具,有你用的东西,当然不会粗过。
Logcat打印信息分为5个等级,如下面几个宏:
#define DLOGE(...) do{__android_log_print(ANDROID_LOG_ERROR , "HALPRINTF", __VA_ARGS__);}while(0);
#define DLOGW(...) do{__android_log_print(ANDROID_LOG_WARN , "HALPRINTF", __VA_ARGS__);}while(0);
#define DLOGI(...) do{__android_log_print(ANDROID_LOG_INFO , "HALPRINTF", __VA_ARGS__);}while(0);
#define DLOGD(...) do{__android_log_print(ANDROID_LOG_DEBUG , "HALPRINTF", __VA_ARGS__);}while(0);
#define DLOGV(...) do{__android_log_print(ANDROID_LOG_VERBOSE , "HALPRINTF", __VA_ARGS__);}while(0);
优先等级是:
E > W > I > D > V
如我想打印“I”以及“I”以上等级的调试信息的时候:
Logcat HALPRINTF:I *:S
这样就实现了调试信息的筛选。
我们平时调试的时候,可能用logcat打印信息的人太多,无奈之下,可能会用“正值表达式”来过滤。但为了不同模块直接的协调性更好,自己的调试信息不会影响到其他人的工作,所以一般会做一个信息开关,实时性地“开”和“关”。
我曾经见过有人用一种比较有趣的方法来做这个开关,就是用android的属性列表。
首先,会创建一个线程,然后在线程里面不停地读android某一项属性,
pthread_create(&XX_id, NULL, &XX_thread, NULL);
static void XX_thread(```)
{
While(1)
{
property_get(“XX.XX.XX”, value, "0");
}
If(0x01 == value - ‘0’)
{
DebugEnable = TRUE;
}
Else
{
DebugEnable = FALSE;
}
}
#define DEBUGSWITCH(code) if(DebugEnable ){code};
这样,代码就弄好了,然后在想开调试信息的时候,用写属性命令:setprop “XX.XX.XX” 1 就OK了。