# By default, esp32 config assumes that FreeRTOS is used. This can be disabled: #set ESP32_RTOS none # Disable RTOS support if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME esp32 } if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { set _CPUTAPID 0x120034e5 } if { [info exists ESP32_RTOS] } { set _RTOS "$ESP32_RTOS" } else { set _RTOS "FreeRTOS" } if { [info exists ESP32_ONLYCPU] } { set _ONLYCPU $ESP32_ONLYCPU } else { set _ONLYCPU 3 } if { [info exists ESP32_FLASH_VOLTAGE] } { set _FLASH_VOLTAGE $ESP32_FLASH_VOLTAGE } else { set _FLASH_VOLTAGE 3.3 } # by default autodetect flash size using flash chip ID, can be overriden by user via OpenOCD command line if { [info exists ESP32_FLASH_SIZE] } { set _FLASH_SIZE $ESP32_FLASH_SIZE } else { set _FLASH_SIZE 0x0 } proc esp_core_halt { tgt } { #We need to disable the watchdogs here. #TIMG1 WDT $tgt mww 0x3FF5F064 0x50D83AA1 $tgt mww 0x3FF5F048 0x0 #TIMG2 WDT $tgt mww 0x3FF60064 0x50D83AA1 $tgt mww 0x3FF60048 0x0 #RTC WDT #ToDo: Figure out how to kill the RTC WDT } proc configure_esp32_core { TGT } { $TGT configure -event halted [list esp_core_halt $TGT] } proc configure_esp32_workarea { TGT } { #WARNING: be careful when selecting working ares for code and data, they should not overlap due to ESP32 physical memory mappings $TGT configure -work-area-phys 0x40090000 -work-area-virt 0x40090000 -work-area-size 0x3400 -work-area-backup 1 # since ESP32 cannot use single address space for code and data we need additional working area to keep data $TGT configure -alt-work-area-phys 0x3FFC0000 -alt-work-area-virt 0x3FFC0000 -alt-work-area-size 0x6000 -alt-work-area-backup 1 } proc configure_esp32_flash_bank { TGT FLASH_SIZE } { set _FLASHNAME $TGT.flash flash bank $_FLASHNAME esp32 0x0000 $FLASH_SIZE 0 0 $TGT # necessary to auto-probe flash bank when GDB is connected $TGT configure -event gdb-attach { halt } } # Determine which target to use if { $_RTOS == "FreeRTOS" && $_ONLYCPU == 3} { # Dual core mode, FreeRTOS support enabled: use the new "esp32" target jtag newtap $_CHIPNAME cpu0 -irlen 5 -expected-id $_CPUTAPID set _TARGETNAME $_CHIPNAME set _TAPNAME $_CHIPNAME.cpu0 target create $_TARGETNAME esp32 -endian little -chain-position $_TAPNAME -rtos $_RTOS configure_esp32_core $_TARGETNAME esp32 flashbootstrap $_FLASH_VOLTAGE configure_esp32_workarea $_TARGETNAME configure_esp32_flash_bank $_TARGETNAME $_FLASH_SIZE } else { # Use esp108 target (either single core mode, or FreeRTOS support disabled) # Change the name of the CPU taps depending on if it's enabled or not. # This way, the user gets immediate feedback in the openocd logs. if { $_ONLYCPU == "1" } { set _CPU0NAME cpu0 set _CPU1NAME ignored } elseif { $_ONLYCPU == "2" } { set _CPU0NAME ignored set _CPU1NAME cpu1 } else { set _CPU0NAME cpu0 set _CPU1NAME cpu1 } #Do add both taps, even if one of the CPUs is disabled. jtag newtap $_CHIPNAME $_CPU0NAME -irlen 5 -expected-id $_CPUTAPID jtag newtap $_CHIPNAME $_CPU1NAME -irlen 5 -expected-id $_CPUTAPID set _TARGETNAME1 $_CHIPNAME.cpu1 set _TARGETNAME2 $_CHIPNAME.cpu0 if { $_ONLYCPU != 2 } { if { $_RTOS == "none" } { target create $_TARGETNAME2 esp108 -endian little -chain-position $_TARGETNAME2 -coreid 0 } else { target create $_TARGETNAME2 esp108 -endian little -chain-position $_TARGETNAME2 -rtos $_RTOS -coreid 0 } configure_esp32_core $_TARGETNAME2 configure_esp32_workarea $_TARGETNAME2 configure_esp32_flash_bank $_TARGETNAME2 $_FLASH_SIZE } if { $_ONLYCPU != 1 } { if { $_RTOS == "none" } { target create $_TARGETNAME1 esp108 -endian little -chain-position $_TARGETNAME1 -coreid 1 } else { target create $_TARGETNAME1 esp108 -endian little -chain-position $_TARGETNAME1 -rtos $_RTOS -coreid 1 } if { $_ONLYCPU != 3 } { configure_esp32_core $_TARGETNAME1 } configure_esp32_workarea $_TARGETNAME1 configure_esp32_flash_bank $_TARGETNAME1 $_FLASH_SIZE } if { $_ONLYCPU != 2 } { targets $_TARGETNAME2 } esp108 flashbootstrap $_FLASH_VOLTAGE } #Force hw breakpoints. Once we have a memory map, we can also allow software bps. gdb_breakpoint_override hard # special function to program ESP32, it differs from the original 'program' that # it verifies written image by reading flash directly, instead of reading memory mapped flash regions proc program_esp32 {filename args} { set exit 0 foreach arg $args { if {[string equal $arg "verify"]} { set verify 1 } elseif {[string equal $arg "reset"]} { set reset 1 } elseif {[string equal $arg "exit"]} { set exit 1 } else { set address $arg } } # make sure init is called if {[catch {init}] != 0} { program_error "** OpenOCD init failed **" 1 } # reset target and call any init scripts if {[catch {reset init}] != 0} { program_error "** Unable to reset target **" $exit } # start programming phase echo "** Programming Started **" if {[info exists address]} { set flash_args "$filename $address" } else { set flash_args "$filename" } if {[catch {eval flash write_image erase $flash_args}] == 0} { echo "** Programming Finished **" if {[info exists verify]} { # verify phase echo "** Verify Started **" if {[catch {eval flash verify_bank 0 $flash_args}] == 0} { echo "** Verified OK **" } else { program_error "** Verify Failed **" $exit } } if {[info exists reset]} { # reset target if requested # also disable target polling, we are shutting down anyway poll off echo "** Resetting Target **" reset run } } else { program_error "** Programming Failed **" $exit } if {$exit == 1} { shutdown } return } add_help_text program_esp32 "write an image to flash, address is only required for binary images. verify, reset, exit are optional" add_usage_text program_esp32 " \[address\] \[verify\] \[reset\] \[exit\]"