由于 ESP32-C3 内部具有内置 JTAG 电路,一般 ESP32-C3 可以直接通过 USB 接口来进行 JTAG 调试。但如果不想用 USB 或者串口,也可以像 ESP32 一样使用 JTAG 适配器(ESP-Prog)来进行固件烧录和 gdb 调试。此篇博客记录 ESP32-C3 使用 ESP-Prog(JTAG) 来烧录固件的流程。此博客分为以下三部分:
注:老版本的 openocd 不支持 ESP32-C3 JTAG 烧录固件,请选用最新版 openocd。此篇博客使用的是 v0.10.0-esp32-20211111。
由于 ESP32-C3 默认选用 内置的 USB_SERIAL_JTAG 外设。此时需要烧录 efuse 来选择外接 JTAG 适配器,有以下两种方式:
烧毁 DIS_USB_JTAG eFuse
: 将永久禁用 USB_SERIAL_JTAG 和 CPU 的 JTAG 端口之间的连接。 然后可以将 JTAG 接口连接到 GPIO4 - GPIO7。 请注意,USB_SERIAL_JTAG 的 USB CDC 功能仍然可用,即仍然可以通过 USB CDC 进行烧录和 log 查看。
烧毁 JTAG_SEL_ENABLE eFuse
: 将启用由 Strapping 引脚 GPIO10 选择的 JTAG 接口。 如果 ESP32-C3 复位时 Strapping 引脚为低电平,则 JTAG 接口将使用 GPIO4 - GPIO7。 如果 Strapping 引脚为高电平,则 USB_SERIAL_JTAG 将用作 JTAG 接口。
这里选择烧毁 JTAG_SEL_ENABLE
, 将 GPIO10 连接至 GND 引脚。在 配置 ESP-IDF 环境 后, 在对应终端输入以下命令:
espefuse.py burn_efuse JTAG_SEL_ENABLE
然后你会得到一个需要输入BURN
的确认信息,如下:
Connecting....
Detecting chip type... ESP32-C3
espefuse.py v3.3-dev
The efuses to burn:
from BLOCK0
- JTAG_SEL_ENABLE
Burning efuses:
- 'JTAG_SEL_ENABLE' (Disables USB JTAG. JTAG access via pads is controlled separately) 0b0 -> 0b1
Check all blocks for burn...
idx, BLOCK_NAME, Conclusion
[00] BLOCK0 is not empty
(written ): 0x000000000000008000000000000000000000800000000000
(to write): 0x000000000000000000000000000000000000020000000000
(coding scheme = NONE)
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
输入BURN
,等待 efuse 烧录完成,然后再次输入 espefuse.py summary
,可以看到 JTAG_SEL_ENABLE
已经为 True
,如下:
espefuse.py summary
Connecting....
Detecting chip type... ESP32-C3
espefuse.py v3.3-dev
EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Config fuses:
DIS_ICACHE (BLOCK0) Disables ICache = False R/W (0b0)
DIS_DOWNLOAD_ICACHE (BLOCK0) Disables Icache when SoC is in Download mode = False R/W (0b0)
DIS_FORCE_DOWNLOAD (BLOCK0) Disables forcing chip into Download mode = False R/W (0b0)
DIS_CAN (BLOCK0) Disables the TWAI Controller hardware = False R/W (0b0)
VDD_SPI_AS_GPIO (BLOCK0) Set this bit to vdd spi pin function as gpio = False R/W (0b0)
BTLC_GPIO_ENABLE (BLOCK0) Enable btlc gpio = 0 R/W (0b00)
POWERGLITCH_EN (BLOCK0) Set this bit to enable power glitch function = False R/W (0b0)
POWER_GLITCH_DSENSE (BLOCK0) Sample delay configuration of power glitch = 0 R/W (0b00)
DIS_LEGACY_SPI_BOOT (BLOCK0) Disables Legacy SPI boot mode = False R/W (0b0)
UART_PRINT_CHANNEL (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0)
UART_PRINT_CONTROL (BLOCK0) Sets the default UART boot message output mode
= Enable when GPIO8 is high at reset R/W (0b10)
FORCE_SEND_RESUME (BLOCK0) Force ROM code to send a resume command during SPI = False R/W (0b0)
bootduring SPI boot
BLOCK_USR_DATA (BLOCK3) User data
= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
Efuse fuses:
WR_DIS (BLOCK0) Disables programming of individual eFuses = 0 R/W (0x00000000)
RD_DIS (BLOCK0) Disables software reading from BLOCK4-10 = 0 R/W (0b0000000)
Flash Config fuses:
FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up, = 0 R/W (0x0)
unit is (ms/2). When the value is 15, delay is 7.
5 ms
FLASH_ECC_MODE (BLOCK0) Set this bit to set flsah ecc mode.
= flash ecc 16to18 byte mode R/W (0b0)
FLASH_TYPE (BLOCK0) Selects SPI flash type = 4 data lines R/W (0b0)
FLASH_PAGE_SIZE (BLOCK0) Flash page size = 0 R/W (0b00)
FLASH_ECC_EN (BLOCK0) Enable ECC for flash boot = False R/W (0b0)
Identity fuses:
SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000)
ure)
MAC (BLOCK1) Factory MAC Address
= 7c:df:a1:76:43:34 (OK) R/W
WAFER_VERSION (BLOCK1) WAFER version = 3 R/W (0b011)
PKG_VERSION (BLOCK1) Package version = ESP32-C3 R/W (0b000)
BLOCK1_VERSION (BLOCK1) BLOCK1 efuse version = 4 R/W (0b100)
OPTIONAL_UNIQUE_ID (BLOCK2) Optional unique 128-bit ID
= 2c 0f 0c 7d e4 65 8d e7 29 7b 5d 8e 7c e8 d5 82 R/W
BLOCK2_VERSION (BLOCK2) Version of BLOCK2 = 5 R/W (0b101)
CUSTOM_MAC (BLOCK3) Custom MAC Address
= 00:00:00:00:00:00 (OK) R/W
Jtag Config fuses:
JTAG_SEL_ENABLE (BLOCK0) Set this bit to enable selection between usb_to_jt = True R/W (0b1)
ag and pad_to_jtag through strapping gpio10 when b
oth reg_dis_usb_jtag and reg_dis_pad_jtag are equa
l to 0.
至此硬件管脚配置 & 连接部分大功告成。
请注意:不要将 JTAG 引脚复用于其他功能,例如复用做外设引脚。
以 配置ESP-IDF 环境 后生成的 helloworld 固件为例进行 JTAG 烧录, 我们需要依次通过 JTAG 将 helloworld 工程的 build 文件夹中的 bootloader.bin、partition-table.bin 和 hello-world.bin 烧写到 ESP32-C3 中。
bootloader.bin
需要输入的命令为:
openocd -f board/esp32c3-ftdi.cfg -c "program_esp build/bootloader/bootloader.bin 0x0 verify exit"
结果如下:
Open On-Chip Debugger v0.10.0-esp32-20211111 (2021-11-10-21:40)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 5000 kHz
Info : clock speed 5000 kHz
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : datacount=2 progbufsize=16
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x40101104
Info : Listening on port 3333 for gdb connections
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : Flash mapping 0: 0x10020 -> 0x3c020020, 27 KB
Info : Flash mapping 1: 0x20020 -> 0x42000020, 73 KB
Info : Auto-detected flash bank 'esp32c3.flash' size 4096 KB
Info : Using flash bank 'esp32c3.flash' size 4096 KB
** Programming Started **
Info : PROF: Data transferred in 146.681 ms @ 136.35 KB/s
** Programming Finished **
** Verify Started **
** Verified OK **
shutdown command invoked
partition-table.bin
需要输入的命令为:
openocd -f board/esp32c3-ftdi.cfg -c "program_esp build/partition_table/partition-table.bin 0x8000 verify exit"
结果如下:
Open On-Chip Debugger v0.10.0-esp32-20211111 (2021-11-10-21:40)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 5000 kHz
Info : clock speed 5000 kHz
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : datacount=2 progbufsize=16
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x40101104
Info : Listening on port 3333 for gdb connections
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Error: Failed to get flash maps (4294967290)!
Warn : Failed to get flash mappings (-4)!
Info : Auto-detected flash bank 'esp32c3.flash' size 4096 KB
Info : Using flash bank 'esp32c3.flash' size 4096 KB
** Programming Started **
Info : PROF: Data transferred in 39.158 ms @ 102.15 KB/s
** Programming Finished **
** Verify Started **
** Verified OK **
shutdown command invoked
hello_world.bin
需要输入的命令为:
openocd -f board/esp32c3-ftdi.cfg -c "program_esp build/hello_world.bin 0x10000 verify exit"
结果如下:
Open On-Chip Debugger v0.10.0-esp32-20211111 (2021-11-10-21:40)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 5000 kHz
Info : clock speed 5000 kHz
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : datacount=2 progbufsize=16
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x40101104
Info : Listening on port 3333 for gdb connections
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Error: Failed to get flash maps (4294967295)!
Warn : Failed to get flash mappings (-4)!
Info : Auto-detected flash bank 'esp32c3.flash' size 4096 KB
Info : Using flash bank 'esp32c3.flash' size 4096 KB
** Programming Started **
Info : PROF: Data transferred in 939.532 ms @ 157.525 KB/s
** Programming Finished **
** Verify Started **
** Verified OK **
shutdown command invoked
然后可以连接串口工具验证固件是否烧录成功,可以看到固件烧录成功并运行,测试后 ESP32-C3 日志如下:
ESP-ROM:esp32c3-api1-20210207␍␊
[15:26:41:956] Build:Feb 7 2021␍␊
[15:26:41:956] rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)␍␊
[15:26:41:961] SPIWP:0xee␍␊
[15:26:41:961] mode:DIO, clock div:1␍␊
[15:26:41:961] load:0x3fcd6100,len:0x1754␍␊
[15:26:41:967] load:0x403ce000,len:0x930␍␊
[15:26:41:967] load:0x403d0000,len:0x2d60␍␊
[15:26:41:967] entry 0x403ce000␍␊
[15:26:41:973] <0x1b>[0;32mI (30) boot: ESP-IDF v5.0-dev-676-g5c33570524-dirty 2nd stage bootloader<0x1b>[0m␍␊
[15:26:41:979] <0x1b>[0;32mI (30) boot: compile time 11:26:33<0x1b>[0m␍␊
[15:26:41:984] <0x1b>[0;32mI (30) boot: chip revision: 3<0x1b>[0m␍␊
[15:26:41:984] <0x1b>[0;32mI (34) boot.esp32c3: SPI Speed : 80MHz<0x1b>[0m␍␊
[15:26:41:990] <0x1b>[0;32mI (39) boot.esp32c3: SPI Mode : DIO<0x1b>[0m␍␊
[15:26:41:996] <0x1b>[0;32mI (43) boot.esp32c3: SPI Flash Size : 2MB<0x1b>[0m␍␊
[15:26:42:001] <0x1b>[0;32mI (48) boot: Enabling RNG early entropy source...<0x1b>[0m␍␊
[15:26:42:007] <0x1b>[0;32mI (54) boot: Partition Table:<0x1b>[0m␍␊
[15:26:42:012] <0x1b>[0;32mI (57) boot: ## Label Usage Type ST Offset Length<0x1b>[0m␍␊
[15:26:42:018] <0x1b>[0;32mI (64) boot: 0 nvs WiFi data 01 02 00009000 00006000<0x1b>[0m␍␊
[15:26:42:023] <0x1b>[0;32mI (72) boot: 1 phy_init RF data 01 01 0000f000 00001000<0x1b>[0m␍␊
[15:26:42:034] <0x1b>[0;32mI (79) boot: 2 factory factory app 00 00 00010000 00100000<0x1b>[0m␍␊
[15:26:42:040] <0x1b>[0;32mI (87) boot: End of partition table<0x1b>[0m␍␊
[15:26:42:046] <0x1b>[0;32mI (91) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=06d08h ( 27912) map<0x1b>[0m␍␊
[15:26:42:051] <0x1b>[0;32mI (104) esp_image: segment 1: paddr=00016d30 vaddr=3fc8a000 size=0145ch ( 5212) load<0x1b>[0m␍␊
[15:26:42:062] <0x1b>[0;32mI (109) esp_image: segment 2: paddr=00018194 vaddr=40380000 size=07e84h ( 32388) load<0x1b>[0m␍␊
[15:26:42:071] <0x1b>[0;32mI (122) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=12658h ( 75352) map<0x1b>[0m␍␊
[15:26:42:079] <0x1b>[0;32mI (136) esp_image: segment 4: paddr=00032680 vaddr=40387e84 size=0209ch ( 8348) load<0x1b>[0m␍␊
[15:26:42:086] <0x1b>[0;32mI (138) esp_image: segment 5: paddr=00034724 vaddr=50000000 size=00010h ( 16) load<0x1b>[0m␍␊
[15:26:42:096] <0x1b>[0;32mI (145) boot: Loaded app from partition at offset 0x10000<0x1b>[0m␍␊
[15:26:42:101] <0x1b>[0;32mI (148) boot: Disabling RNG early entropy source...<0x1b>[0m␍␊
[15:26:42:107] <0x1b>[0;32mI (165) cpu_start: Pro cpu up.<0x1b>[0m␍␊
[15:26:42:118] <0x1b>[0;32mI (173) cpu_start: Pro cpu start user code<0x1b>[0m␍␊
[15:26:42:118] <0x1b>[0;32mI (174) cpu_start: cpu freq: 160000000 Hz<0x1b>[0m␍␊
[15:26:42:123] <0x1b>[0;32mI (174) cpu_start: Application information:<0x1b>[0m␍␊
[15:26:42:129] <0x1b>[0;32mI (177) cpu_start: Project name: hello_world<0x1b>[0m␍␊
[15:26:42:135] <0x1b>[0;32mI (182) cpu_start: App version: v5.0-dev-676-g5c33570524-dirty<0x1b>[0m␍␊
[15:26:42:140] <0x1b>[0;32mI (189) cpu_start: Compile time: Dec 21 2021 11:26:26<0x1b>[0m␍␊
[15:26:42:145] <0x1b>[0;32mI (195) cpu_start: ELF file SHA256: aef53b86d4475353...<0x1b>[0m␍␊
[15:26:42:151] <0x1b>[0;32mI (201) cpu_start: ESP-IDF: v5.0-dev-676-g5c33570524-dirty<0x1b>[0m␍␊
[15:26:42:162] <0x1b>[0;32mI (208) heap_init: Initializing. RAM available for dynamic allocation:<0x1b>[0m␍␊
[15:26:42:168] <0x1b>[0;32mI (215) heap_init: At 3FC8C2C0 len 00033D40 (207 KiB): DRAM<0x1b>[0m␍␊
[15:26:42:174] <0x1b>[0;32mI (221) heap_init: At 3FCC0000 len 0001F060 (124 KiB): STACK/DRAM<0x1b>[0m␍␊
[15:26:42:179] <0x1b>[0;32mI (228) heap_init: At 50000010 len 00001FF0 (7 KiB): RTCRAM<0x1b>[0m␍␊
[15:26:42:185] <0x1b>[0;32mI (235) spi_flash: detected chip: generic<0x1b>[0m␍␊
[15:26:42:192] <0x1b>[0;32mI (239) spi_flash: flash io: dio<0x1b>[0m␍␊
[15:26:42:199] <0x1b>[0;33mW (243) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.<0x1b>[0m␍␊
[15:26:42:207] <0x1b>[0;32mI (256) sleep: Configure to isolate all GPIO pins in sleep state<0x1b>[0m␍␊
[15:26:42:218] <0x1b>[0;32mI (263) sleep: Enable automatic switching of GPIO sleep configuration<0x1b>[0m␍␊
[15:26:42:223] <0x1b>[0;32mI (270) cpu_start: Starting scheduler.<0x1b>[0m␍␊
[15:26:42:228] Hello world!␍␊
至此可以证明外部 JTAG 适配器已经成功烧写 ESP32-C3 的固件。