ESP32-C3 使用 ESP-Prog (JTAG) 烧录固件过程

由于 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。

1 硬件管脚配置 & 连接

由于 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 引脚,引脚连接 定义如下:
ESP32-C3 使用 ESP-Prog (JTAG) 烧录固件过程_第1张图片

至此硬件管脚配置 & 连接部分大功告成。

请注意:不要将 JTAG 引脚复用于其他功能,例如复用做外设引脚。

2 软件指令 & 测试结果

以 配置ESP-IDF 环境 后生成的 helloworld 固件为例进行 JTAG 烧录, 我们需要依次通过 JTAG 将 helloworld 工程的 build 文件夹中的 bootloader.bin、partition-table.bin 和 hello-world.bin 烧写到 ESP32-C3 中。

2.1 烧录 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

2.2 烧录 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

2.3 烧录 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 的固件。

3 其他功能补充

  • ESP32-C3 JTAG 调试

你可能感兴趣的:(芯片烧录,(Chip,Programming),单片机,嵌入式硬件)