MTK调试入门之一------TRACE使用的技巧

52RD上曾有朋友让我写一些调试技巧方面的文章.调试对于软件是十分重要的,但却不是一篇二篇文章能讲清楚的.有不少调试技巧都是零零碎碎的东西,用的时候能很容易使用,但要写出来时,却仍是比较麻烦的.html

MTK的调试通常来讲能够分为仿真调试与手机调试.这两种调试对于研发新功能,修改BUG,研究算法都是十分重要的.固然,这两种调试也有差别,有时会出如今模拟器运行正常,在手机却运行失败,或者相反,这就突出了软件模拟环境与硬件手机环境的差异.缘由多是各类各样的,好比多是有些硬件软件没有办法模拟,有些新功能对硬件依赖强,不能模拟,新软件的有些函数只能在手机上运行,没有写相应的模拟器代码.等等缘由都会致使二者差别.这里不一一赘述,你们知道模拟器和手机有差别就好了.算法

模拟器调试具备直观,快速,追踪方便能优势,受到不少MMI开发者的喜欢.而有关模拟器的调试,其余也就是VC调试功能的使用.因为国内软件教育重编程,算法,轻调试,因此不多有系统的调试方书的书.在开发过程当中,我也见过许多人压根就不使用模拟器,他们认为模拟器也就是在没有手机的时候使用.详细讲解模拟器的调试就放到之后,由于模拟器断点,内存,堆栈,变量各个方面的调试,详细写来均可以成一篇文章.这里先讲一个手机调试的TRACE使用.之前曾写过一篇DUMP调试的文章.经过出错的DUMP信息查找错误.有兴趣的朋友能够参考. Detail_RD.Blog_blogercn_19169.html编程

 

1.在MTK平台,咱们最常使用的TRACE函数是kal_prompt_trace函数,这个函数是系统提供给咱们的用于在catcher里调试错误的.在这个函数不能使用的场合,有时咱们会使用函数system_print或者dbg_printf,这两个函数能够不使用catcher的状况,使用WIN自带的工具超级终端来调试程序.有时驱动的朋友会本身用函数PutUARTBytes写自已TRACE函数,这些函数可使用超级终端调试,以下,就是别人写的一个TRACE函数.打印某一块数据的内容,经常TRACE内存数据,指定地址,指定大小网络

void perun_dump(void *buf, prn_int16 size)函数

{工具

#ifdef PRN_TRACE_OPEN优化

#ifdef MMI_ON_HARDWARE_Pui

    char    str[2048];编码

    char   *ptr = (char*)str;.net

    char   *ptr1 = buf;

    int     i = 0;

 

    memset(str, 0, sizeof(str));

    strcpy(ptr, "[Perun_dump]: ");

    ptr += strlen("[Perun_dump]: ");

 

    while (i < size)

    {

        sprintf(ptr, " %02x", *ptr1);

        ptr += 3;

        ++ptr1;

        ++i;

    }

    sprintf(ptr, "\r\n");

 

    PutUARTBytes(0, (kal_uint8 *)str, (kal_uint16)strlen(str));

#endif

#endif

}

也能够写一个像MTK自带的同样的函数来TRACE,以下,该函数也是能够运行在终端中:

Void perun_trace(char *fmt, ...)

{

#ifdef PRN_TRACE_OPEN

#ifdef MMI_ON_HARDWARE_P

    va_list list;

    char    buf[2048];

    char   *ptr = (char*)buf;

 

    memset(buf, 0, sizeof(buf));

    strcpy(ptr, "[Perun_trace]: ");

    ptr += strlen("[Perun_trace]: ");

 

    va_start(list, fmt);

    vsprintf(ptr, fmt, list);

    va_end(list);

 

    strcat(buf, "\r\n");

       buf[2047] = 0;

    PutUARTBytes(0, (kal_uint8 *)buf, strlen(buf));

#endif

#endif

}

2.TRACE语句的编写是十分重要的.如何写出的TRACE既能在仿真下使用,也能在手机中使用,我通常会使用以下的格式:

#ifdef WIN32

#define MYTRACE printf

#else

#define MYTRACE(...) kal_prompt_trace(MOD_WAP, __VA_ARGS__)

#endif

通过以下的封装,MYTRACE就能够既能在手机上运行,也能在电脑中运行, 而且我已经消除了MTK自带的函数与printf在调用上的不一样.顺便说一下,模拟器调用函数MYTRACE时,会在控制制输出该函数的打印信息.手机调用MYTRACE时,会在filiter为MOD_WAP时输出信息.

3.有时为了便于观察,我会为个人TRACE语句添加一个前缀,好比我本身的TRACE前面添加十个>或者我本身的拼音名字,我会以下修改个人MYTRACE:

#ifdef WIN32

#define MYTRACE printf

#else

#define STR(s) #s

#define MYTRACE(...) kal_prompt_trace(MOD_WAP, STR(>>>>>>>>>>)##__VA_ARGS__)

#endif

通过这样的改进,个人TRACE在输出信息时,信息头就是个人名字,我可使用查找所有功能把我须要的TRACE全抓出来.若是你对#号的使用,有疑问,请本身查找相关资料

4.种种迹象和从理论上看来,TRACE和MMI_ASSERT是调试的好帮手,但在发布软件时,带上了这个会引来没必要要的麻烦.MMI_ASSERT增长了系统重启的频率.TRACE增长了系统的ROM,RAM和CPU的开销.在工做中,咱们曾经发现一款手机,因为ROM过于紧张,添加几条TRACE就会出现编译错误,去掉TRACE就编译经过了,致使出了BUG调试十分的麻烦.如何写一种使用时能够TRACE错误,不使用时又不占用系统资源的TRACE呢,我见许多人这样处理,由于NULL会被编译器优化点,后面括号变成一个表达式了.表达式对系统的开销天然小于函数了.

#ifdef DEBUG_KAL

#define MYTRACE(...) kal_prompt_trace(MOD_WAP, __VA_ARGS__)

#else

#define MYTRACE NULL

#endif

 

我通常这样操做.

#ifdef DEBUG_KAL

#define MYTRACE(...) kal_prompt_trace(MOD_WAP, __VA_ARGS__)

#else

#define MYTRACE //

#endif

我曾经认为这样写能够在不使用时,把宏函数变为注释符,但个人一个朋友认为这样写,并不能把个人函数变成注释符,他的道理是双斜线会被编译器外忽略掉,我认为是有道理的,后来个人朋友通过思考,写出以下的TRACE,经过一个反斜杠的链接符,哄编译器在展开宏时把两个斜杠连起来组成注释符,这个写法有些古怪,下面的单个斜杠必须顶格写,以保证通过链接合,两斜杠之间没有空格从而在被编译时与后面的代码组成注释行.但这样写的一个致命的缺陷是会让许多人看不明白.另外一个缺陷时不美观

#ifdef DEBUG_KAL

#define MYTRACE printf

#else

#define MYTRACE /\

/

#endif

5.有关C语言的古怪用法,据 的做者曾说,世界上有一个古怪的大赛叫”国际C语言混乱代码大赛”,每一年举办一次.获奖的都功能齐全而代码惨不忍睹的典型.在MTK上,也曾经有一段费了我很大功夫的TRACE代码:

#define DBG_PRINTF(_x_) \

do{ \

printf("%s(%d)--:",__FILE__,__LINE__);\

printf  _x_; \

}while(0);

当时怎么想都不明白为何会有这么古怪的使用printf  _x_;后来才发现使用时要加双层括号才能正常使用。

6.在手机与网络,手机与电脑的交互过程当中,有时咱们须要TRACE数据包的内容,特别在显示不正确或者不精确的状况下,须要研究数据包的数据是使用UTF编码,还UCS2编码,仍是ASC编码,这时咱们就须要TRACE数据的字节内容,从而便于分析。我通常使用下面这个本身随手写的函数来实现.


static U8 TraceUni(U8 *str, U8 len)
{
 U8 *tempstr,*tempascstr;
 U8 i;
 
 tempstr = str;
 kal_prompt_trace(MOD_MMI, "XXXXXXXXXXXXXXXXXXXXXXXX   Trace mmi_msg_handle_new_msg_ind is start    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
 if (*(tempstr + 1) == 0x00)
 {
  UnicodeNToAnsii((S8*)tempascstr,(S8*)tempstr,len );
  kal_prompt_trace(MOD_MMI, "jone trace, the string = %s", tempascstr);
 }
 else
 {
  for (i = 0; (*tempstr != NULL) || (*(tempstr+1) != NULL) && (len-- != 0); i++)
  {
   kal_prompt_trace(MOD_MMI, "jone trace, the string[%d] = %x", i, *(tempstr++));
  }
 }
 kal_prompt_trace(MOD_MMI, "XXXXXXXXXXXXXXXXXXXXXXXX   Trace string is end      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
 
 return 0;
}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/blogercn/archive/2009/10/28/4739732.aspx

相关文章
相关标签/搜索