OpenOCD is used to drive the JTAG interface, typically in conjunction with GDB for code execution debugging. The usage of GDB is fundamentally no different from its use in other contexts.Some debugging techniques for GDB: Advanced Usage of GDBThere are two ways to start GDB and interact with OpenOCD:
- GDB communicates with OpenOCD over TCP network
>openocd -f ocd.cfg # Start OpenOCD >gdb # Start GDB (gdb) target extended-remote localhost:3333 # Connect to OpenOCD
- GDB communicates with OpenOCD through a Linux pipe (|)
>gdb # Start GDB (gdb) target extended-remote | openocd -f ocd.cfg -c "gdb_port pipe; log_output /tmp/openocd.log" # Start OpenOCD, GDB uses pipe to interact with OpenOCD
The second method, combined with GDB’s script execution capability, allows a set of debugging commands to be placed in a batch process. The command line for GDB’s -x option is as follows:
--command=file-x file Execute GDB commands from file.
For example, editing the following gdb.cmds can dump a segment of memory, and after the dump is complete, exit GDB on the third line:
target extended-remote | openocd -f ocd.cfg -c "gdb_port pipe; log_output /tmp/openocd.log"monitor dump_image /tmp/memory.dump 0x60000000 1024quit
The dump_image command is as follows:
Command: dump_image filename address size Dump size bytes of target memory starting at address to the binary file named filename.
For example, error injection in software testing. For instance, consider the following code:
void handle_msg(struct msg *amsg){ uint32_t actual_crc = calc_crc(amsg); if (actual_crc != amsg->expected_crc) { handle_msg_crc_error(amsg); } else { handle_msg_forward(amsg); }}
Generally, it is difficult for a normally running system to encounter a CRC error. Therefore, the fifth line of code is rarely executed, so we can use GDB’s scripted execution method to inject an error without affecting the normal flow of execution. For example, the following script sample.cmd:
printf "Connect the remote OpenOCD target"target extended-remote | openocd -f ocd.cfg -c "gdb_port pipe; log_output /tmp/openocd.log" printf "Break handle_msg"break handle_msgcommand 1 set amsg->expected_crc=0 continueend continue
Start GDB with -x sample.cmd target.elf to execute debugging.Below is a detailed explanation of this script sample.cmd:
- line 2: Connect to OpenOCD, and once connected, the debug target will stop running
- line 5: Set a breakpoint above handle_msg
- line 6: Set the action to take when the handle_msg breakpoint (number 1) is hit
- line 7: Manually modify expected_crc to ensure the CRC check will fail
- line 8: Continue execution after the breakpoint is hit
- line 11: The connection to OpenOCD in line 2 halts execution; after setting is complete, execution is resumed here
Since this is a scripted method, it generally does not produce negative effects caused by interruptions during debugging. Note that the script should not quit at the end, keeping the debugging mode online, allowing for continuous error injection.