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 0x0c08 0x0c2b ftdi_layout_signal nSRST -data 0x0400 # 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
$ cat tcl/interface/ftdi/mbftdi.cfg interface ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0008 0x000b
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