Use GDB debug embedded system
1. Better We will learn to use GDB to debug embedded systems connected to PCs with a PC through a serial line. GDB can debug a variety of programs, including C, C , Java, Pascal, Foran, and some other languages. Includes the assembly language of all microprocessors supported by the GNU. Among all the rumorable properties of GDB, it is worth noting that when the platform (host host) running GDB is connected to the target board by serial port (or network connection, or other means) (application) The program runs on the board), and GDB can debug the application to debug the application. This feature is not only useful to transplant the GNU tool to a new operating system or microprocessor, it is also very useful for designers developed by the embedded system of the chip that GNU already supported. When GDB is properly integrated into an embedded system, its remote debugging function allows designers to debug program code step by step, set breakpoints, verify memory, and exchange information with the target. GDB exchange information with the target board is quite strong, better than most commercial debug kernels, and even functionality is equivalent to some low-end emulators. 2. GDB functions when debugging a remote target device when debugging a remote target device, relying on a debug stub to complete its function. Debug STUB is a small piece of code in an embedded system, which provides a medium between the host machine and the debugged application running GDB. GDB and debug STUB communicate via GDB serial protocol. The GDB serial protocol is a message-based ASCII code protocol that includes commands such as read and write memory, query registers, running programs. Because most embedded system designers have written their own stubs in order to make specific hardware features in their hands. So we need to understand the GDB serial communication protocol. Behind we will introduce. In order to set breakpoints, GDB uses memory readback commands, without harming the original instruction with a trap command or other similar opcode (assuming, the debugged application is in RAM, of course, if STUB There is a good performance, the hardware is also good, this condition is not a must) instead, so that when executing this command, the control can be transferred to the debug stub hand. At this time, the debug STUB task is to transfer the current scene to GDB (via a remote serial communication protocol), then receive commands from the GDB, which tells Stub's next step. For explanation, the following code is a TRAP exception handler of the Hitachi SH-2 processor: / * Store the value of the current register to the stack * / / * then call GDB_EXCEPTION. * / Asm (".global _GDB_EXCEPTION_32 _GDB_EXCEPTION_32: / * Press the stack pointer and R14 in the stack * / Mov.l R15, @ -r15 mov.l r14, @ -r15 / * When performing a trap abnormality, SH2 automatically places PC and SR into the stack * / / * So we have to adjust our stack pointer value to GDB, in order to explain this special data * / / * in other words, before the trap is executed, GDB wants to see the value of the stack pointer, * / / * rather than traps Perform the current value.
* / * So, subtract 8 * / / * from the SP value just pressing the stack (PC and SR is 4 bytes) * / mov.l @ (4, r15), R14 Add # 8, R14 MOV.L R14, @ (4, r15) / * Press other register values to stack * / Mov.l R13, @ -R15 MOV.L R12, @ -R15 MOV.L R11, @ -R15 MOV .l r10, @ -R15 mov.l r9, @ -r15 mov.l r8, @ -R15 mov.l r7, @ -r15 mov.l r5, @ -r15 mov.l R4, @ -r15 mov.l r3, @ -r15 mov.l r2, @ -r15 mov.l r1, @ -r15 sts.l macl, @ -r15 st.l Mach, @ -r15 STC VBR, R7 STC GBR, R6 STS PR, R5 / * Calls GDB_EXCEPTION to make it exception value = 32 * / mov.l _GDB_EXCEPTION_TARGET, R1 JMP @ R1 MOV # 32, R4 .align 2 _GDB_EXCEPTION_TARGET: .long _GDB_Exception "); / * The following is a sample (for Hitachi SH2) * / / * if Hitachi SH2) * / / * is written in the C language, then the prototype of the statement is: * / / * void gdb_return_from_exception (GDB_SH2_REGISTERS_T Registers); * / / * In summary, we can use GDB_EXCEPTION_NN to press the register into the stack in the same way * / / * will pop up from the stack. However, it usually returns a pointer to our return stack pointer. * / / * So if we pop up R15 before copying the PC and SR, we will return to * / lose the PC and SR.
* / Asm (".global _GDB_RETURN_FROM_EXCEPTION _GDB_RETURN_FROM_EXCEPTION: / * Restore certain registers * / lds R4, Pr LDC R5, GBR LDC R6, VBR LDS R7, MACH LDS.L @ R15 , MACL MOV.L @ R15 , R0 MOV. L @ r15 , r1 mov.l @ r15 , r2 mov.l @ R15 , R3 Mov.L @ R15 , R4 MOV.L @ R15 , R6 MOV.L @ R15 , R7 MOV.L @ R15 , R8 MOV.L @ R15 , R9 MOV.L @ R15 , R10 MOV.L @ R15 , R11 MOV.L @ R15 , R12 / * Pop up PC and SR to the application stack * / mov.l @ (8, R15), R14 MOV.L @ (16, R15), R13 MOV.L R13, @ -R14 MOV.L @ (12, R15), R13 MOV.L R13, @ -r14 / * Complete recovery register Work * / mov.l @ R15 , R13 MOV.L @ R15 , R14 MOV.L @ R15, R15 / * Adjust the stack of the application to explain the PC, SR * / Add # -8, R15 / *.. Returns to the application * / RTE NOP "); when the processor encounters a trap instruction (this instruction is set by GDB, it is used for breakpoints), the instruction makes the current scene of the processor turn to a named GDB_EXCEPTION. )The function. Finally, the target calls the GDB_RETURN_FROM_EXCEPTION () function that restores the processor's scene and handles the control to the application. The step command of the remote serial protocol is slightly more challenging, especially when the target processor does not provide a "tracking bit" or similar function. In these cases, the only alternative is to make Stub to reverse the instructions to be executed. This will know where the program will be executed next. Fortunately, in the source code of GDB, it also provides suggestions on how to implement these closer commands. For Hitachi SH-2 chip, the use of function dosstep () is described in the GDB / SH-stub.c file. For other kinds of chips, the name of the function is similar, please see file GDB / I386-Stub.c And GDB / M68K-stub.c 3. Other functions of GDB can also solve the values of any C expressions entered in the console, including expressions including functional functions that have a function function of the far end. We can enter the following command: Print foo (sh_sci [current_sci] -> smr.brg) GDB will pass the value of MR.BRG to Foo () and report its return value. Of course, GDB can also disassemble code. As long as it is possible, it can also provide the equivalent symbol information for the required data. For example, GDB outputs the following: JMP 0x401010 tells us that the displayed address is offset from the start address of the function main () to the address of 80 bytes.
GDB can display remote serial debugging information between its own and debugged targets, or record this information
Go to the log file. These features have commissioned a new stub, understand how Stub is using a remote serial contend
It is very useful to implement the user's demand for data, program memory, system calls, etc. GDB has a scripting language that allows automatic settings and detection to the target. This language is independent of the target processor
, The application can be reused when the application is placed from a target processor to another processor.
Finally, GDB also provides a function of tracking points, which can record information of a running program, and
Can not interrupt the program to collect data. Trace points require special debug stubs to implement.
4. A typical GDB session process
Now we have explored the generic function of GDB, now let's take a look at the execution of GDB. The following is given
Typical GDB debugging session process. In this process, GDB initializes the same remote target for running debug stubs.
Communication, then download the program, set breakpoints, and run the program. When you encounter breakpoints, debug STUB notification
GDB, GDB then displays its source code line to the user. Next, the user shows a variable, step by step.
Instructions, then introducing GDB.
Note that the content you see when you are using GDB is not shown below. The user see is a terminal.
The content displayed is used in English, and the variables to be displayed, etc. However, the script description shown below
The content that occurs behind the scene when the user is typed.
Description of a typical GDB session process
The content of the user typed on the serial port.
GDB Send Target Response
Host> GDB MyProgram
GDB> Target Remote / dev / ttys0
GDB> LOAD
GDB> BreakPoint Main [Nothing. GDB is physically set up breakpoint before the subsequent command is sent]
GDB> Continue
[Program run until the main () function]
[Target stop at Main (), address is 0x4015cc]
GDB> Display Foo $ 2F86 # 06
[Foo address is 0x4015BC; its value is 0x2f86]
GDB> STEPI
[Target execution a directive]
[PC value is now 0x4015CE]
GDB> quit
In the above figure, the left column shows part of the GDB console. Type commands and monitor data here. right
The side is displayed some communication messages between the host and the embedded device using the GDB remote serial protocol. At the party
Some explanations are some interpreted in parentheses. If you want to know the meaning of this information, please see Appendix "GDB remote serial"
Agreement section.
5. GDB debugging STUB source code
Although remote software debugging has a property dependent, it is still possible to create a highly portable
Sexual debug STUB, can be reused between different embedded processor chips, and the required modifications are minimal.
Some people have tried this work. If you are interested, you can go online to consult the relevant information. example
Such as http://sourceforge.net/projects/gdbstubs.
The processor-specific code is included in the file name associated with the processor, such as GDB_SH2 * .c. We can
Download our specific processor (such as GDB_M68K * .c), then replace our machine with it
The relevant content.
6. About transforming GDB to solve specific problems
GDB uses a modular architecture to achieve, then some of the features that are not suitable for what we need.
Can be treated directly. For example, if our product has only one communication port, and it is not a GDB communication protocol, then the GDB can be modified, so that the debugger's information is already using our products.
The packet matches.
Similarly, if our products do not have a serial port, while some other communication interfaces (such as CAN ports),
Then we can strengthen the remote communication function of GDB to adapt to the port.
We can also modify the GDB's way to make it more compatible with our embedded applications. For example, if
If we are using Trapa # 32 to do some work with GDB, we can change GDB to set breakpoints
And use the operand, or we can use GDB to generate a new message tells us the target board to open the finger.
Make the tracking function or enable the breakpoint in the chip to generate hardware.
The file GDB / Remote.c contains the implementation process of the remote serial protocol of GDB. For modularity of GDB
How is the implementation allows us to quickly transform it to accommodate a specific debugger, this file is a good start.
point. Other files, such as GDB / Remote-HMS.C and GDB / Remote-E7000.c, using this modular
The structure is supported for debuggers and emulators such as Hitachi, Motorola and other companies.
7. to sum up
GDB's adaptability to debug targets (including the use of the memory, communication medium, etc.) make it
For the commissioning of the target board, it is often the only choice. Considering the single-chip high integration, IP-based embedded
This is the case. Today, the complexity of embedded devices is increasing, in progress
When the choice of choice is more and more, it is increasingly difficult to find a business development product.
The use of GNU tools will be a good choice. GNU tools for various popular embedded processors
When we are using the development tool that we will use by the processor we want to use in the next design,
We can reduce the danger of finding new development tools.
http://www.linuxforum.net/doc/gdb.doc