ESP32 JTAG
来自Jack's Lab
目录 |
1 Quick Start
1.1 Build the OpenOCD
$ sudo apt-get install libftdi-dev make libtool pkg-config autoconf automake texinfo $ git clone --recursive git://github.com/espressif/openocd-esp32.git $ cd openocd-esp32 $ ./bootstrap $ ./configure --enable-openjtag_ftdi $ make && sudo make install
1.2 Prepare Hardware
- Noduino Quantum board
- FT2232H breakout board
Connections:
- FT2232H_PIN16_ADBUS0_TCK ---> Quantum_IO13 (ESP32_MTCK_GPIO13)
- FT2232H_PIN17_ADBUS1_TDI ---> Quantum_IO12 (ESP32_MTDI_GPIO12)
- FT2232H_PIN18_ADBUS2_TDO ---> Quantum_IO15 (ESP32_MTDO_GPIO15)
- FT2232H_PIN19_ADBUS3_TMS ---> Quantum_IO14 (ESP32_MTMS_GPIO14)
- FT2232H_GND ---> ESP32_GND
- Connect FT2232H breakout board and Quantum board into USB port of your PC
- Connect Quantum board into USB port of your PC
1.3 Configuration
We supply a OpenOCD config file for Quantum board using the FT2232H breakout board:
$ echo $IDF_PATH /work/xwifi/esp-idf $ cat $IDF_PATH/docs/quantum.cfg
# # OpenOCD configuration file to hook up Noduino Quantum board to a JTAG # adapter. Please modify this file to your local setup. # # Include the configuration for the JTAG adapter. We use the general FT2232H breakout # board here. If you have a different interface, please edit this to include the # configuration file of yours. #source [find interface/ftdi/tumpa.cfg] interface ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0038 0x003b # The ESP32 only supports JTAG. transport select jtag # The speed of the JTAG interface, in KHz. If you get DSR/DIR errors (and they # do not relate to OpenOCD trying to read from a memory range without physical # memory being present there), you can try lowering this. adapter_khz 200 # With no variables set, openocd will configure JTAG for the two cores of the ESP32 and # will do automatic RTOS detection. This can be be adjusted by uncommenting any of the # following lines: # Only configure the PRO CPU #set ESP32_ONLYCPU 1 # Only configure the APP CPU #set ESP32_ONLYCPU 2 # Disable RTOS support #set ESP32_RTOS none # Force RTOS to be FreeRTOS #set ESP32_RTOS FreeRTOS #Source the ESP32 configuration file source [find target/esp32.cfg] # The TDI pin of ESP32 is also a bootstrap pin that selects the voltage the SPI flash # chip runs at. When a hard reset happens (e.g. because someone switches the board off # and on) the ESP32 will use the current TDI value as the bootstrap value because the # JTAG adapter overrides the pull-up or pull-down resistor that is supposed to do the # bootstrapping. These lines basically set the idle value of the TDO line to a # specified value, therefore reducing the chance of a bad bootup due to a bad flash # voltage greatly. # Enable this for 1.8V SPI flash #esp108 flashbootstrap 1.8 # Enable this for 3.3V SPI flash esp108 flashbootstrap 3.3
Make sure the VID and PID of your FT2232H breakout board are matched with your mbftdi.cfg otherwise you can modify the mbftdi.cfg to match :
$ lsusb | grep 0403 | grep 6010 Bus 008 Device 004: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
1.4 Debug
Open a bash window and run:
$ cd /path/to/openocd-esp32 $ sudo ./src/openocd -s ./tcl -f ./esp32.cfg # start OpenOCD Open On-Chip Debugger 0.10.0-dev-g3098897-dirty (2016-11-06-00:39) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html adapter speed: 200 kHz force hard breakpoints Info : clock speed 200 kHz Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1) Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Push the reset buttom on the Quantum board, you can see the openocd output:
Info : esp32.cpu0: Debug controller was reset (pwrstat=0xFF, after clear 0xFF). Info : esp32.cpu0: Core was reset (pwrstat=0xFF, after clear 0xFF). Info : esp32.cpu1: Debug controller was reset (pwrstat=0xFF, after clear 0xFF). Info : esp32.cpu1: Core was reset (pwrstat=0xFF, after clear 0xFF). Info : esp32.cpu0: Target halted, pc=0x400809C4 esp32.cpu0: target state: halted
ESP32 is enter JTAG debug mode now.
Open a new bash window and run:
$ cd /path/to/esp-idf/examples/06_wifi_scan $ xtensa-esp32-elf-gdb build/app-template.elf GNU gdb (crosstool-NG 8d95cad) 7.10 Copyright (C) 2015 Free Software Foundation, Inc. ...... ...... Reading symbols from build/wifi-scan.elf...done. (gdb) tar remo localhost:3333 Remote debugging using localhost:3333 ipc_task (arg=0x0) at /work/xwifi/esp-idf/components/esp32/./ipc.c:45 45 { (gdb) i r pc 0x400809c4 0x400809c4 <ipc_task> lbeg 0x0 0 lend 0x0 0 lcount 0x0 0 sar 0x0 0 ps 0x50020 327712 threadptr 0x0 0 br 0x0 0 scompare1 0x0 0 acclo 0x0 0 acchi 0x0 0 m0 0x0 0 m1 0x0 0 m2 0x0 0 m3 0x0 0 expstate 0x0 0 f64r_lo 0x0 0 f64r_hi 0x0 0 f64s 0x0 0 fcr 0x0 0 fsr 0x0 0 a0 0x0 0 a1 0x3ffc1580 1073485184 a2 0x0 0 a3 0x0 0 ...... ...... (gdb) b app_main Breakpoint 1 at 0x400d1af8: file /work/xwifi/esp-idf/examples/06_wifi_scan/main/./app_main.c, line 64. (gdb) c Continuing. esp32.cpu0: Target halted, pc=0x400D1AF8 [New Thread 1073491756] [New Thread 1073493740] [New Thread 1073485304] [Switching to Thread 1073489792] Breakpoint 1, app_main () at /work/xwifi/esp-idf/examples/06_wifi_scan/main/./app_main.c:64 64 { (gdb) i thr Id Target Id Frame 4 Thread 1073485304 (No Name) 0x400820f6 in xQueueGenericReceive (xQueue=0x3ffc1054, pvBuffer=0x0, xTicksToWait=4294967295, xJustPeeking=0) at /work/xwifi/esp-idf/components/freertos/./queue.c:1589 3 Thread 1073493740 (Svc) 0x40083b52 in prvProcessTimerOrBlockTask (xNextExpireTime=0, xListWasEmpty=<optimized out>) at /work/xwifi/esp-idf/components/freertos/./timers.c:487 2 Thread 1073491756 (No Name) prvIdleTask (pvParameters=0x0) at /work/xwifi/esp-idf/components/freertos/./tasks.c:3220 * 1 Thread 1073489792 (No Name : Running) app_main () at /work/xwifi/esp-idf/examples/06_wifi_scan/main/./app_main.c:64
Welcome to GDB world :)
2 GDB Tips
2.1 Display Register
(gdb) i r a # show all registers including float and multimedia (gdb) i r pc 0x40080f7f 0x40080f7f <_xt_medint3+23> lbeg 0x0 0 lend 0x0 0 lcount 0x0 0 sar 0x1e 30 ps 0x60e33 396851 threadptr 0x0 0 br 0x0 0 scompare1 0xb33f0000 3007250432 acclo 0x0 0 acchi 0x0 0 m0 0x0 0 m1 0x0 0 m2 0x0 0 m3 0x0 0 expstate 0x0 0 f64r_lo 0x0 0 f64r_hi 0x0 0 f64s 0x0 0 fcr 0x0 0 fsr 0x0 0 a0 0x400ecf6b 1074712427 a1 0x3ffc4e90 1073499792 a2 0x17 23 a3 0x3ffc178c 1073485708 a4 0x1 1 a5 0x3ffc47b0 1073498032 a6 0x3ffc478c 1073497996 a7 0x1 1 a8 0x3ffb 16379 a9 0x3ffc4f30 1073499952 a10 0x3ffb0048 1073414216 a11 0x3ffc1780 1073485696 a12 0x3ffbfe68 1073479272 a13 0x0 0 a14 0x3ffc4848 1073498184 a15 0x3ffc4810 1073498128 (gdb) i r pc pc 0x40080f7f 0x40080f7f <_xt_medint3+23> (gdb) i r epc1 epc1 0x0 0
2.2 Display Memory
(gdb) x /4wx 0x40080000 # Display the data at the specified address in hexadecimal 0x40080000 <_WindowOverflow4>: 0x1049c500 0xe52049d5 0x49f53049 0x00003400 (gdb) i r pc pc 0x400809c4 0x400809c4 <ipc_task> (gdb) x /8x $pc 0x400809c4 <ipc_task>: 0x30004136 0x3d3003eb 0x10123704 0x2cfeaba1 0x400809d4 <ipc_task+16>: 0xfeaac1fb 0x10feabd1 0x48252011 0xfea93150 (gdb) x /4x $pc+12 0x400809d0 <ipc_task+12>: 0x2cfeaba1 0xfeaac1fb 0x10feabd1 0x48252011 (gdb) x /s 0x3f401330 # Display the data at the specified address as a string 0x3f401330: "Scanned %d APs \r\n" (gdb) x /8i $pc # Display the data at the specified address as instruction (24 instructions) => 0x400d1a3f <scan_ap_task+35>: l32r a8, 0x400d01f8 <_stext+480> 0x400d1a42 <scan_ap_task+38>: callx8 a8 0x400d1a45 <scan_ap_task+41>: l16ui a2, a1, 16 0x400d1a48 <scan_ap_task+44>: addx2 a10, a2, a2 0x400d1a4b <scan_ap_task+47>: addx4 a10, a10, a2 0x400d1a4e <scan_ap_task+50>: slli a10, a10, 2 0x400d1a51 <scan_ap_task+53>: l32r a8, 0x400d00c8 <_stext+176> 0x400d1a54 <scan_ap_task+56>: callx8 a8
2.3 Modify Register
(gdb) i r a0 a0 0x0 0 (gdb) set $a0=0x55aa (gdb) i r a0 a0 0x55aa 21930 (gdb) set $pc = 0x4008020c
2.4 Modify Memory
(gdb) set {unsigned int}0x40080a51=0x0 (gdb) set *(unsigned int*)0x40080a54=0x55aa
2.5 Search Memory
Usage: find <start> <end> <count> <value> (gdb) define find set $ptr = $arg0 set $cnt = 0 while ( ($ptr<=$arg1) && ($cnt<$arg2) ) if ( *(unsigned int *)$ptr == $arg3 ) x /wx $ptr set $cnt = $cnt + 1 end set $ptr = $ptr + 4 end end
2.6 Breakpoint & Watchpoint
(gdb) b *0x40080506 (gdb) watch *(unsigned int *)0x40081020==0x90909090