一. 添加各种打印
1.Kernel中的打印
a.添加自己的打印函数
-
在include/linux/kernel.h中printk之后:
-
#define DEBUG 1
-
#if DEBUG
-
#define dbmsg(fmt, args ...) printk(KERN_NOTICE "%s:%s[%d]: "fmt"\n", __FILE__,__FUNCTION__, __LINE__,##args)
-
#else
-
#define dbmsg(fmt, args ...)
-
#endif
b. 打印16进制数
-
用(unsigned int)将(base/1024/1024)括起来
-
dbmsg("base=%dM,size=%dM",(unsigned int)(base/1024/1024),(unsigned int)(size/1024/1024));
c.16进制打印结构体
-
a.实现
-
int dump_raw_char(char* p, int len)
-
{
-
int i;
-
printk("usb_raw: ");
-
for(i=0; i<len; i++)
-
printk("0x%02x ", (unsigned char)p[i]);
-
printk("\n");
-
return 0;
-
}
-
EXPORT_SYMBOL_GPL(dump_raw_char);
-
b. 在头文件中添加定义
-
extern int dump_raw_char(char* p, int len);
-
-
c. 使用
-
dump_raw_char((char*)dr,sizeof(struct usb_ctrlrequest));
d.利用内核自带的函数, 打印堆栈信息
e. 打印错误字符串
dbmsg("%s",strerror(errno));
2. Android下C/C++中加打印
a.程序文件中添加打印
在文件system/core/include/cutils/log.h的末尾添加
或者/system/core/include/log/log.h的末尾添加
-
#define TAG_CONG "cong"
-
#define LOG_CONG(...) __android_log_print(ANDROID_LOG_INFO, TAG_CONG, __VA_ARGS__)
-
#define dbmsg(x, ...) LOG_CONG("%s:%s(%d), "x,__FILE__, __FUNCTION__,__LINE__, ##__VA_ARGS__)
-
其中打印级别是:
-
ANDROID_LOG_ERROR > ANDROID_LOG_WARN > ANDROID_LOG_INFO > ANDROID_LOG_DEBUG
-
-
包含的头文件: #include
Android.mk: LOCAL_LDLIBS += -llog
b.在Android.mk中添加打印
-
$(warning "the value of LOCAL_PATH is$(LOCAL_PATH)")
c.在Android 中的c/c++中打印堆栈
-
#include <utils/CallStack.h> //在system/core/include/utils/CallStack.h中
-
android::CallStack stack;
-
stack.update(1, 100);
-
stack.log("cong"); //注意:这儿是log,而不是传说中的dump
-
编译时在Android.mk中添加库
-
LOCAL_SHARED_LIBRARIES += libutils
3.在shell中添加打印
4. perl中打印出行号与文件名
-
print "tmd:",__FILE__,"[",__LINE__,"]","\n";
-
print ("tmd:",__FILE__,"[",__LINE__,"]","\n");
5.Makefile的脚本中的打印
-
在规则内部用的是echo
-
@echo "tmd: Codegen.mak[613]: nvram_auto_gen"
-
在规则外部打印变量用的是warning $(warning "tmd:build.mak L2505")
6. java中打印行号
-
public String getLineInfo()
-
{
-
StackTraceElement ste = new Throwable().getStackTrace()[1];
-
return ste.getMethodName()+ "[" + ste.getLineNumber()+"]: ";
-
}
使用时: Log.i(TAG,getLineInfo() + "hello");
7.c中宏只打印文件名
c中用__FILE__, 会打印现文件的完整路径,像mtk平台这个路径会很长,如果想只打印文件名怎么办呢?
-
#include <iostream>
-
using namespace std;
-
-
#define _STRRCHR_IMPL_COMMON(str, ch, offset) (str)[sizeof((str)) - 1 - (offset)] == (ch)? (str) + sizeof((str)) - (offset): sizeof((str)) <= (offset) + 1? (str)
-
-
#define _STRRCHR_IMPL_31(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 31): (str))
-
#define _STRRCHR_IMPL_30(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 30): _STRRCHR_IMPL_31(str, ch))
-
#define _STRRCHR_IMPL_29(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 29): _STRRCHR_IMPL_30(str, ch))
-
#define _STRRCHR_IMPL_28(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 28): _STRRCHR_IMPL_29(str, ch))
-
#define _STRRCHR_IMPL_27(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 27): _STRRCHR_IMPL_28(str, ch))
-
#define _STRRCHR_IMPL_26(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 26): _STRRCHR_IMPL_27(str, ch))
-
#define _STRRCHR_IMPL_25(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 25): _STRRCHR_IMPL_26(str, ch))
-
#define _STRRCHR_IMPL_24(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 24): _STRRCHR_IMPL_25(str, ch))
-
#define _STRRCHR_IMPL_23(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 23): _STRRCHR_IMPL_24(str, ch))
-
#define _STRRCHR_IMPL_22(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 22): _STRRCHR_IMPL_23(str, ch))
-
#define _STRRCHR_IMPL_21(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 21): _STRRCHR_IMPL_22(str, ch))
-
#define _STRRCHR_IMPL_20(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 20): _STRRCHR_IMPL_21(str, ch))
-
#define _STRRCHR_IMPL_19(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 19): _STRRCHR_IMPL_20(str, ch))
-
#define _STRRCHR_IMPL_18(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 18): _STRRCHR_IMPL_19(str, ch))
-
#define _STRRCHR_IMPL_17(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 17): _STRRCHR_IMPL_18(str, ch))
-
#define _STRRCHR_IMPL_16(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 16): _STRRCHR_IMPL_17(str, ch))
-
#define _STRRCHR_IMPL_15(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 15): _STRRCHR_IMPL_16(str, ch))
-
#define _STRRCHR_IMPL_14(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 14): _STRRCHR_IMPL_15(str, ch))
-
#define _STRRCHR_IMPL_13(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 13): _STRRCHR_IMPL_14(str, ch))
-
#define _STRRCHR_IMPL_12(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 12): _STRRCHR_IMPL_13(str, ch))
-
#define _STRRCHR_IMPL_11(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 11): _STRRCHR_IMPL_12(str, ch))
-
#define _STRRCHR_IMPL_10(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 10): _STRRCHR_IMPL_11(str, ch))
-
#define _STRRCHR_IMPL_9(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 9): _STRRCHR_IMPL_10(str, ch))
-
#define _STRRCHR_IMPL_8(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 8): _STRRCHR_IMPL_9(str, ch))
-
#define _STRRCHR_IMPL_7(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 7): _STRRCHR_IMPL_8(str, ch))
-
#define _STRRCHR_IMPL_6(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 6): _STRRCHR_IMPL_7(str, ch))
-
#define _STRRCHR_IMPL_5(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 5): _STRRCHR_IMPL_6(str, ch))
-
#define _STRRCHR_IMPL_4(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 4): _STRRCHR_IMPL_5(str, ch))
-
#define _STRRCHR_IMPL_3(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 3): _STRRCHR_IMPL_4(str, ch))
-
#define _STRRCHR_IMPL_2(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 2): _STRRCHR_IMPL_3(str, ch))
-
#define _STRRCHR_IMPL_1(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 1): _STRRCHR_IMPL_2(str, ch))
-
#define _STRRCHR_IMPL_0(str, ch) (_STRRCHR_IMPL_COMMON(str, ch, 0): _STRRCHR_IMPL_1(str, ch))
-
-
// a macro version of strrchr().
-
// it has several limitations:
-
// - str must be a literal string, e.g. "a string".
-
// - if ch cannot be found in last 32 characters, it will return the whole string.
-
// this limit can be increased by adding more _STRRCHR_IMPL_* macros.
-
#define _STRRCHR(str, ch) (sizeof((str)) <= 1? (str): _STRRCHR_IMPL_0(str, ch))
-
-
#define __FILENAME__ _STRRCHR(__FILE__, '/')
-
-
int main() {
-
cout << "full file path: \t" << __FILE__ << endl;
-
cout << "short filename: \t" << __FILENAME__ << endl;
-
cout << endl;
-
-
cout << "case 1: \n expected: \tefgh.c\n actual: \t" << _STRRCHR("0123/2345/4567/6789/8901/0123/2345/4567/6789/abcd/cdef/efgh.c", '/') << endl;
-
cout << "case 2: \n expected: \tabcdcdefefgh.c\n actual: \t" << _STRRCHR("abcdcdefefgh.c", '/') << endl;
-
cout << "case 3: \n expected: \tabcd/cdef/0123456789012345678901234567890.c\n actual: \t" << _STRRCHR("abcd/cdef/0123456789012345678901234567890.c", '/') << endl;
-
return 0;
-
}
参考:
8.实现一个简单的printf
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <stdarg.h>
-
-
static void itoa(char **buf, int i, int base)
-
{
-
char *s;
-
#define LEN 20
-
int rem;
-
static char rev[LEN+1];
-
-
rev[LEN] = 0;
-
if (i == 0)
-
{
-
(*buf)[0] = '0';
-
++(*buf);
-
return;
-
}
-
s = &rev[LEN];
-
while (i)
-
{
-
rem = i % base;
-
if (rem < 10)
-
*--s = rem + '0';
-
else if (base == 16)
-
*--s = "abcdef"[rem - 10];
-
i /= base;
-
}
-
while (*s)
-
{
-
(*buf)[0] = *s++;
-
++(*buf);
-
}
-
}
-
char print_buf[256];
-
void dbg_print(char *fmt,...)
-
{
-
va_list ap;
-
double dval;
-
int ival;
-
char *p, *sval;
-
char *bp, cval;
-
int fract;
-
unsigned short len;
-
bp= print_buf;
-
*bp= 0;
-
-
va_start (ap, fmt);
-
for (p= fmt; *p; p++)
-
{
-
if (*p != '%')
-
{
-
*bp++= *p;
-
continue;
-
}
-
switch (*++p) {
-
case 'd':
-
ival= va_arg(ap, int);
-
if (ival < 0){
-
*bp++= '-';
-
ival= -ival;
-
}
-
itoa (&bp, ival, 10);
-
break;
-
-
case 'o':
-
ival= va_arg(ap, int);
-
if (ival < 0){
-
*bp++= '-';
-
ival= -ival;
-
}
-
*bp++= '0';
-
itoa (&bp, ival, 8);
-
break;
-
-
case 'x':
-
ival= va_arg(ap, int);
-
if (ival < 0){
-
*bp++= '-';
-
ival= -ival;
-
}
-
*bp++= '0';
-
*bp++= 'x';
-
itoa (&bp, ival, 16);
-
break;
-
-
case 'c':
-
cval= va_arg(ap, int);
-
*bp++= cval;
-
break;
-
-
case 's':
-
for (sval = va_arg(ap, char *) ; *sval ; sval++ )
-
*bp++= *sval;
-
break;
-
}
-
}
-
*bp= 0;
-
printf("%s",print_buf); //在pc机上测试用的是printf,真正用时把这个函数替换即可
-
va_end (ap);
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
dbg_print("cong:%s%s%d\n",__FILE__,__FUNCTION__,__LINE__);
-
return EXIT_SUCCESS;
-
}
有了myprintf这个函数就可以定义dbmsg了,实现自动打印文件名函数名+行号
#define dbmsg(fmt, args ...) myprintf("%s:%s[%d]: "fmt"\n", __FNAME__,__FUNCTION__, __LINE__,##args)
二. 单独编译与清除某个模块
1. 内核如果想单独编译touchscreen模块
-
sun@ubuntu:/work/ok_linux-3.0.1$ make CONFIG_TOUCHSCREEN_S3C=m -C./ M=./drivers/input/touchscreen/ modules
-
sun@ubuntu:/work/ok_linux-3.0.1$ make -C./ M=./drivers/video/ clean
清除时 只需要把-M后面的路径改一下就可以了
2. android 平台
-
cong@ubuntu:/work/an6410/an2.3.4$ export TARGET_PRODUCT=OK6410
-
cong@ubuntu:/work/an6410/an2.3.4$ mmm ./hardware/libhardware/modules/gralloc/
三. 内核的一些小问题
1. rmmod 出错
-
[错误]: rmmod: chdir(/lib/modules): No such file or directory
-
[解决]: 建目录 /lib/modules/
-
[又错]: rmmod: chdir(3.0.1): No such file or directory
-
[解决]: 建目录 /lib/modules/3.0.1
2. irq释放时
-
request_irq(IRQ_EINT(0), button_interrupt, IRQF_TRIGGER_FALLING, "KEY1", NULL); //注册irq
-
free_irq(BUTTON_IRQ, button_interrupt); //释放irq
-
出现以下问题:
-
WARNING: at kernel/irq/manage.c:1147 __free_irq+0x9c/0x180()
-
Trying to free already-free IRQ 101
-
[解]:
-
request_irq(IRQ_EINT(0), button_interrupt, IRQF_TRIGGER_FALLING, "KEY1", NULL); //注册irq
-
free_irq(BUTTON_IRQ, NULL); //释放irq
-
注册与释放时最后一个参数必须相同
3. 把zImage镜像copy出来
在arch/arm/boot/Makefile中添加
-
56 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
-
57 $(call if_changed,objcopy)
-
58 cp -f arch/arm/boot/zImage ./
-
59 @echo ' Kernel: $@ is ready
4. 删除内核中没有参与编译的文件
a. 在当前目录中查找.c文件
b. 将查找到的.c转为.o,若不存在,说明这个.c没有编译,删除
c. 将没有编译的.c文件的头文件去掉
-
#!/bin/sh
-
for cf in `find . -maxdepth 1 -name "*.c"`
-
do
-
of=`echo "$cf" | sed 's/\.c/\.o/'`
-
if [ ! -f "$of" ]; then
-
rm $cf
-
echo "rmcf $cf"
-
hf=`echo "$cf" | sed 's/\.c/\.h/'`
-
if [ -f "$hf" ]; then
-
rm $hf
-
echo "rmhf $hf"
-
fi
-
fi
-
done
注: 只对当前目录有效,删除还是需要谨慎的.若不想谨慎去掉 find中的maxdepth
四. android端的技巧:
1.设置dns
setprop net.dns1 8.8.8.8
2. 设置打开飞行模式时wifi不关闭
-
root@78P01:/ # settings get global airplane_mode_radios
-
cell,bluetooth,wifi,nfc,wimax
-
root@78P01:/ # settings put global airplane_mode_radios "cell,bluetooth,nfc"
-
root@78P01:/ # settings get global airplane_mode_radios
-
cell,bluetooth,nfc
阅读(2193) | 评论(0) | 转发(0) |