There are three basic debugging methods for MTK development: TRAC and serial port.
For normal interface modification, the function line can be basically completed through the simulator. However, when a crash or l4c-related problem occurs, you need to use TRAC and Cather for debugging. If the problem persists, then, MTK will tell you to turn on the dump switch, capture packets through TRAC, upload the packet to eservice, and then analyze the cause of the problem. The serial port mode is mainly used by many third-party applications on the MTK platform;
Method 1: simulator debugging
The previous article introduced the trace technique for mobile phone debugging. MTK mobile phone debugging is relatively simple. In addition to trace, search for assert, and analyze dump, the rest is experience, experienced people can guess what the problem is, simply look at the trace to confirm their guesses. it often takes time for first-time friends to accumulate experience. to be proficient, you need to read more research code when you are free. having mastered the code, you will be able to solve the problem.
MTK simulator debugging is not a skill, but a skill is also good, because the simulator technology is not so much about MTK experience as VC experience.
Because the simulator can do a lot of UI development without a prototype, and the simulator has the advantages of being quick, WYSIWYG, and changed, it is favored by many developers. mastering the simulator usage skills is of positive significance for improving work efficiency and saving resources.
To do this, you must first sharpen the tool. To learn about simulator debugging, you must first understand VC usage. The shortcut keys frequently used during VC debugging are as follows:
Use of VC ++ breakpoint: Press F9 (Set breakpoint), F5 debugging, F10 single-step debugging, Shift + F5 to exit debugging F10 single statement execution, F11 single command execution, CTRL + F10: Execute to the cursor; F9: Set/cancel breakpoints by line; Alt + F9: set breakpoints by line, by data, or by message; during debugging, press Alt + 3 to open the tracking window, ALT + 4 to open the Variable Window, ALT + 5 to open the register window, ALT + 6 to open the memory window, ALT + 7 to open the Stack window, alt + 8 open the assembly instruction window;
1. as long as you have source code, it is easy to have a simulator. of course, in some cases, this is also difficult for first-time MTK users, especially for companies with poor code management, a large number of employees, and frequent employee turnover, you can never imagine how bad their code will be. however, I usually try to use their code to compile the simulator in a new company. No matter how bad their code is, I can quickly compile the simulator. there are only three steps:
A. before compiling the simulator, please turn off all sp macros. This is very important. Many SP do not provide the libraries running in the simulator. Therefore, the more SP programs a project has, in the simulator, the more functions he cannot recognize.
B. if an error occurs during compilation, you can use the # ifdef Win32 macro to enclose all codes irrelevant to the display, and use typedef int xxx; to redefine all types that you do not know. use Win32 to include unrecognized macro definitions and redefine them.
C. A large number of unknown functions will be encountered during the generation of MnS. If there are fewer than 50 functions, void XXX () {} type empty functions will all be built. if there are more than one hundred functions, try to find the source of these functions. If there is a related sp, try again to disable the related sp. of course, if you are not in trouble, you can also build these one hundred functions into empty functions. generally, If you disable all third-party functions and mtk-independent functions, the number of unidentifiable functions will not exceed 10.
After three steps, you can generally get a simulator that is almost usable. with the simulator, you can do the following work. if you still cannot obtain the simulator, it is recommended that you consult your project leader. If your leader cannot solve the problem, it means that the software group is a fast member change, or lacks a rational department, of course, it is also possible that programmers in this department are top-notch MTK workers and their programs never need to be debugged. in short, this is a crazy department.
2. if you get to a simulator, you can start debugging. first, there are three types of breakpoints in VC: Local breakpoint, data breakpoint (also called conditional breakpoint, or advanced breakpoint), and message breakpoint; these three types of breakpoints correspond to the three tabs in the dialog box opened by the shortcut key "Alt + F9. because the message breakpoint is used to track win messages, it is not required in MTK. in the simulator, we generally only use local breakpoints and data breakpoints. local breakpoints and data breakpoints play an important role in bug debugging. Mastering breakpoint skills can make your work more efficient. Some people may use breakpoints, but they do not know what they can do in the simulator. breakpoint has two most commonly used functions: one is to track code execution, and the other is to observe the changes in the local variable value at the breakpoint. these two functions are used most. however, he has two implicit functions in the MTK simulator. One is to quickly locate the file. The source code of MTK is about tens of thousands of files. After SP is added, the Code has exceeded tens of thousands. it is very difficult to search for a function. In this case, you need to use a breakpoint. in the code reading tool Si, you can easily use "Ctrl + O" to open the file, or use "F7" to quickly locate the function, but it is not so convenient in VC, however, you can use breakpoints. For example, if you want to open a file wgui_categories_cm.c in VC, as long as you use "Alt + F9" in VC
In the at edit box, enter {, E: \ jmt_1120 \ plutommi \ MMI \ GUI \ gui_src \ wgui_categories_cm.c ,}. 4693. After pressing F5 to execute debug, VC can locate the 4693 line of the wgui_categories_cm.c file. This is a file breakpoint. You can also set a function breakpoint. For example, the 4693 line of the wgui_categories_cm.c file corresponds to the showcategory16screen function. You can also enter showcategory16screen in the break at edit box and use the F5 key to debug, when the function runs on the dial-up interface, it stops for debugging. The local breakpoint is used in this way. So what is the use of local breakpoints? Or is there any special purpose? Here are a few simple examples. However, breakpoints can be used to solve a lot of problems. Don't use my examples to constrain your imagination.
A. How can I use a breakpoint to quickly locate a problem? If we find that there is a problem in the dialing window, but we are not familiar with the code and do not know which file and line of the dialing window code are located, we can break points on the entrynewscreen function, when the dial-up is enabled, the system stops. In this case, we can easily find the implementation function of the window through the Stack window information. After studying the code in detail, you can find a solution.
B. breakpoint can be used to quickly solve the window display problem. For example, in our dial-up window, an image is not normally displayed. In this case, we can place a breakpoint on the drawing function gdi_image_codec_draw and enter the dial-up window, every time an image is displayed, it will stop on the function. Combined with the stack, we can easily find out where the code came out and solve the problem. there are too many such functions.
C. breakpoint can be used to study the problem of accidental modification of global variables. In the breakpoint dialog box, select the second tab and enter the variables to be tracked. When each variable changes, VC will stop and wait for us to debug. you can also set a condition. Assume that an error occurs when the value of a global variable u8 g_xxx is 5, but you do not know where the global variable is assigned 5 by any code, in this case, you can set a data breakpoint. In the dialog box above the second tab, enter g_xxx = 5. When the value is 5, it will stop.
D. research code can also use breakpoints. For example, MTK code contains a lot of function pointer encapsulation, such as gui_print_text pointer. You want to study its implementation process, but because it is a pointer, you cannot find his function body. In this case, you can input the pointer gui_print_text in the Data breakpoint. When the simulator is restarted, he will locate the ui_print_text function.
Here are four examples. breakpoints can be used in any scenario where debugging is required. However, too many breakpoints may affect the speed of searching for problems, you can break certain variables and functions to solve the problem. this is an accumulation process
3. stack debugging. Alt + 7 open the Stack window. in this window, we can see the call relationship between functions. This is very useful. It is generally used in combination with breakpoints. It is very useful to locate bugs and study code. the above example will not be used here.
4. in the Variable Window, ALT + 4 open the variable window, which will automatically display the variables used in the breakpoint code and their values. Read the code to solve the bug and use it. During single-step execution, you will often refer to the data in this window.
5. watch window, press Alt + 3 to open it. Because the variables automatically displayed in the Variable Window are sometimes not needed, we can drag and drop the variables we need to view to this window for research, it's great to use it in combination with breakpoints, and expression values are also supported here.
6. in the memory window, ALT + 6 open the memory window. The memory window can display a piece of memory content, which is very useful. For example, if we want to track the text message content, there is a pointer to the text message content, input the pointer into the Watch window and you can only see the first value pointed to by the pointer. It is very troublesome to look at other values. You can only enter the expression, but you can enter the pointer into the memory window, you don't have to bother yourself.
7. alt + 8 open the assembly instruction window, which is not very useful. Learning assembly is still useful. in general, if a third-party library file has a problem, you can only use this window for debugging. under normal circumstances, if the error is located in the assembly code of the C standard library file, there is only one possibility that your call is wrong.
Debugging takes a large part of the R & D time. The basic debugging technology is like this. Generally, it is integrated and flexible to solve the problem and stabilize the code. the rest is the problem of experience accumulation.
Note:
MTK Introduction
Perform the following operations on the PC simulation of the MNS: (assume that the project path is D: \ x)
Step 1: In the following Directory D: \ x
Execute make prj_name GPRS gen_mrm
Step 2: Go to the directory "D: \ x \" to run "createmodem.pl .. \ make \ prj_name_upls.mak" in the directory "D: \ x \".
Step 3: Switch to D: \ x
Execute make prj_name GPRS codegen_mrm.
Step 4: Go to the directory of the image processing service,
Run modiscodegen. Pl .. \ make \ prj_name_upls.mak
Step 5: run the D: \ x \ modem\ modem.dsw command to compile the project;
Step 6: Start the MNS-> boot-> Option-> luanch catcher & NS to simulate the operation and obtain logs from the catcher;
Note: In earlier versions of catcher, NS cannot be controlled.
Make wmd6225_gemini GPRS gen_mrm
CD mocs
Createsdf. Pl .. \ make \ wmd6225_gemini_upls.mak
CD ..
Make wmd6225_gemini GPRS codegen_mrm
CD mocs
Modiscodegen. Pl .. \ make \ wmd6225_gemini_upls.mak
Method 2: Debug TRAC in Catcher Mode
Some friends asked me to write some articles on debugging skills. debugging is very important for the software, but it is not clear in one or two articles. there are a lot of debugging skills that are fragmented and easy to use, but it is quite troublesome to write.
MTK debugging can be divided into simulation debugging and mobile phone debugging. these two types of debugging are very important for R & D of new functions, modification of bugs, and research of algorithms. of course, there are also differences between the two types of debugging. Sometimes the simulator runs normally but fails on the mobile phone, or vice versa, this highlights the differences between the software simulation environment and the hardware mobile phone environment. there may be various reasons. For example, some hardware software cannot be simulated. Some new features are highly dependent on hardware and cannot be simulated. Some functions of new software can only run on mobile phones, no simulator code is written. and so on. I will not repeat it here. We all know that there is a difference between the simulator and the mobile phone.
Simulator debugging is intuitive, fast, and easy to trace. It is favored by many MMI developers. other functions, such as VC debugging, are used for simulator debugging. because Software Education in China focuses on programming, algorithms, and debugging, there are very few books on system debugging. during the development process, I have seen many people not use simulators at all. They think that simulators are used when there is no mobile phone. the debugging of the simulator will be later, because the debugging of the breakpoint, memory, stack, and variable of the simulator can be written in detail into an article. here we will first talk about the trace usage for mobile phone debugging. I have previously written an article on dump debugging. locate the error by using the dump information. if you are interested, refer. detail_rd.blog_blogercn_19169.html
1. on the MTK platform, the most commonly used trace function is the kal_prompt_trace function, which is provided by the system for debugging errors in catcher. when this function cannot be used, sometimes we use the system_print or dbg_printf function. The two functions can debug the program using the Super Terminal provided by win without using the catcher function. sometimes drivers use the putuartbytes function to write their own trace functions. These functions can be debugged using a Super Terminal. Below is a trace function written by others. print the content of a piece of data, often trace memory data, specify the address, specify the size
Void perun_dump (void * Buf, prn_int16 size)
{
# Ifdef prn_trace_open
# Ifdef mmi_on_hardware_p
Char STR [2048];
Char * PTR = (char *) STR;
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
}
You can also write a function like the one that comes with MTK for trace. The function can also be run on the terminal as follows:
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. The preparation of Trace statements is very important. How to Write a trace can be used in both simulation and mobile phones? The following format is generally used:
# Ifdef Win32
# Define mytrace printf
# Else
# Define mytrace (...) kal_prompt_trace (mod_wap, _ va_args __)
# Endif
After the following encapsulation, mytrace can be run on both the mobile phone and the computer, and I have eliminated the differences between the functions provided by MTK and that of printf. by the way, when the simulator calls the function mytrace, it will output the print information of the function in the control system. when the mobile phone calls mytrace, it will output information when Filiter is mod_wap.
3. sometimes, for convenience of observation, I will add a prefix for my trace statements, for example, add 10> or my own pinyin name before my own trace. I will modify my mytrace as follows:
# Ifdef Win32
# Define mytrace printf
# Else
# Define STR (s) # s
# Define mytrace (...) kal_prompt_trace (mod_wap, STR (>>>>>>>>>>) ##__ va_args __)
# Endif
With this improvement, the information header is my name when I output the trace information. I can use all the functions to find all the traces I need. if you have any questions about the use of #, please find the relevant information by yourself
4. there are various signs and theoretically, trace and mmi_assert are good helpers for debugging, but when releasing software, this will lead to unnecessary trouble. mmi_assert increases the frequency of system restart. trace increases system ROM, ram, and CPU overhead. at work, we once found a mobile phone. Due to the shortage of Rom, a compilation error will occur when several traces are added, and the trace is compiled after it is removed, debugging of bugs is very troublesome. how to Write a trace error that can be used in use without occupying system resources during use? I have seen many people handle this problem because null will be optimized by the compiler, And the parentheses will become an expression. the overhead of the expression is naturally less than the function.
MTK uses trace stack information to find the cause and solution of the Bug (20:00:21)
I went to a company a few days ago to help them solve the bug. The bug is described as follows. When using online QQ, if you call, it will restart.
No assert information is found, and only stack dump information is found. At first, I heard their descriptions, and they felt like QQ or phone call problems.
After capturing the trace, we found it was a problem with the med module, because med is mainly used to decode some media files.
When we observe the phenomenon, we find that the call has not been able to ring the bell before it starts to restart. Therefore, we can probably infer that a problem has occurred when the call rings,
Find the trace information for specific locations. The trace information obtained from others is as follows:
Trace 1745424 150706 mod_nil trace_error [1] fatal error (4): data_abort-med
Trace 1745424 150706 mod_nil trace_error exception type: Data abort
Trace 1745424 150706 mod_nil trace_error software version:
E500_a.1.4
Trace 1745424 150706 mod_nil trace_error Boot Mode: Normal Mode
Trace 1745424 150706 mod_nil trace_error RTC sec = 16, RTC min = 33, RTC hour = 1
Trace 1745424 150706 mod_nil trace_error RTC day = 1, rtc mon = 1, RTC wday = 1, RTC year = 9
Trace 1745424 150706 mod_nil trace_error Execution Unit: medmed
Trace 1745424 150706 mod_nil trace_error status: 0x00000000
Trace 1745424 150706 mod_nil trace_error Stack pointer: 0x00169380
Trace 1745424 150706 mod_nil trace_error stack dump:
Trace 1745424 150706 mod_nil trace_error 0x08520.c9
Trace 1745424 150706 mod_nil trace_error 0xa0001bed
Trace 1745424 150706 mod_nil trace_error 0x08520.c9
Trace 1745424 150706 mod_nil trace_error 0x08520.c9
Trace 1745424 150706 mod_nil trace_error 0x08480fd5
Trace 1745424 150706 mod_nil trace_error 0x0847ce59
Trace 1745424 150706 mod_nil trace_error 0x084de0ef
Trace 1745424 150706 mod_nil trace_error 0x0866d4d3
Trace 1745424 150706 mod_nil trace_error 0x0845e407
Trace 1745424 150706 mod_nil trace_error 0x0866d4a1
Trace 1745424 150706 mod_nil trace_error number of messages in the external queue: 0
Trace 1745424 150706 mod_nil trace_error messages in the external queue:
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Trace 1745424 150706 mod_nil trace_error msg_id_invalid_type
Observe the trace and combine the bug description to roughly infer that it is med's ringing problem. You need to check the stack information printed by the catcher for the specific location.
Some people may be overwhelmed by this information. When I first learned MTK, I still had no way to start. I always felt that this information was not as intuitive as assert.
You can see which file has an error. However, assert is not always a gold medal. Once I met a memcpy assert, there were too many calls,
We still need to check the stack information to find the problem. Of course, to write the code, try to add asset in some key areas, which makes it easier to find problems.
Of course, with this information, we can also estimate the location and cause of the bug. To find the error information, you must find the corresponding software version.
. The sym and binfile are both generated in the build file. This file stores the address generated by the arm compiler for all functions in the software.
When an error occurs, MTK will save the address of the 10 most recently executed commands in the stack at that time. By studying these addresses, we can find the error.
Because the sym file only saves the address of the function, the address of the Code executed in the function body is not listed, and the error address is not exactly corresponding to the address of a function.
Address, which is usually offset by N Units. Of course, there are also exceptions. I encountered an error where an address exactly corresponds to a function address. For error messages
The address does not correspond to the function address. I guess it should be a command error in the function body, so we should find the nearest function that is smaller than the error command.
For example, in the previous routine "trace 1745424 150706 mod_nil trace_error 0x08520.c9", we should not find 0x08520.c9 In the sym file.
The corresponding command, because one can not be found, we need to find the x085569c or x085569 pair of functions, then we can find a lot of functions,
Find the function corresponding to the address closest to the error address and smaller than the address. About 10 functions can be found for 10 addresses. After careful troubleshooting,
Confirm the following functions:
Med_int_left_size
Med_int_sfreeaud_main
Aud_tts_play_req_hdlr
Med_int_smalloc
Med_set_ext_memory_pool
Tcc_task_shell
In this way, you can roughly determine the source and cause of the problem. Ask the project owner to learn about aud_tts_play_req_hdlr.
It is the playing function of the voice player. When calling, there is a call report number. Both the function and QQ dynamically allocate memory from the med stack. Because QQ occupies a memory and calls an incoming call, the voice master fails to allocate memory, causing a speech decoding failure. Solve the problem.
========================================================== ========================================================== =====
It is one of the most common debugging methods to find the function entry that causes the problem through map information. In fact,
You can also find the problem through symptom analysis. For example, it is easy to find a fixed path for this completely reproducible problem.
For example, if the incoming call prompt is changed to vibrate or silent, what will happen? If the incoming call number is closed, what will happen. The problem is solved. Shared Memory causes this problem,
In fact, it is not considered during the design, and it does not take into account various possible boundary. It may not be good to use assert too much. As a debugging method,
If all of them are out of the factory, assert or restart them everywhere to solve some problems. It seems so bad.
3. Serial Port debugging
MTK serial port debugging sets the only serial port used by at and debug when the MTK product is released.
Generally, the AT command and download code use Serial Port 1 (app uses uart_port1 ),
Debug debugging generally uses Serial Port 2 (TST uses uart_port2 ).
The Code may set Serial Port 2 and Serial Port 3 as common Io ports. Therefore, in the program debugging stage, if you want to enable at debugging and debug simultaneously, you need to configure the gpio settings of uart_port2.
Setting Method: Go to custom \ DRV \ drv_tool, use drvgen.exe to open custom \ DRV \ misc_drv \ "project name" \ codegen. DWS, and set the gpio corresponding to the UART port.
If you only want to change the serial port of TST and at debugging information, you only need to set:
./Custom/common/pluto_mmi/nvram_common_config.c nvram_ef_port_setting_default []
0x00, 0x00,/* TST uses uart_port2 (value is 1) * // longfeey modify 0x01, 0x00,
0x01, 0x00,/* app uses uart_port1 * // longfeey modify 0x00, 0x00,
0 x, 0x00 indicates the serial port x 01, and 0x00 indicates the serial port 2
Set as needed.