Skip to content

openocd

编译

使用

  • erase all
openocd -f wch-riscv.cfg -c init -c halt -c "flash erase_sector wch_riscv 0 last " -c exit
openocd -f wch-riscv.cfg -c init -c halt -c "flash erase_sector wch_riscv 0 last " -c exit
  • program
openocd -f wch-riscv.cfg  -c init -c halt  -c "program xxx.hex\bin\elf "  -c exit
openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "program stm32f103x.elf"  -c "reset" -c shutdown
openocd -f wch-riscv.cfg  -c init -c halt  -c "program xxx.hex\bin\elf "  -c exit
openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "program stm32f103x.elf"  -c "reset" -c shutdown
  • verify
openocd -f wch-riscv.cfg -c init -c halt -c "verify_image xxx.hex\bin\elf"    -c exit
openocd -f wch-riscv.cfg -c init -c halt -c "verify_image xxx.hex\bin\elf"    -c exit
  • reset and resume
openocd -f wch-riscv.cfg -c init -c halt -c wlink_reset_resume    -c exit
openocd -f wch-riscv.cfg -c init -c halt -c wlink_reset_resume    -c exit
#i.maxrt
if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
} else {
    set _CHIPNAME imxrt
}

source [find mem_helper.tcl]

# ---------------------------------------------- Auxiliary functions for accessing i.MXRT registers ----------------------------------------------


# SBMR2: Bit 25..24:
# BOOT_MODE[1:0]: 00b - Boot From Fuses
#                 01b - Serial Downloader
#                 10b - Internal Boot
#                 11b - Reserved
proc get_boot_mode {} {
    set SRC_SBMR2 [ mrw 0x400F801C ]
    set bootmode [ expr {($SRC_SBMR2 & 0x03000000) >> 24} ]
    return $bootmode
}

# Boot Device: 0000b - Serial NOR boot via FlexSPI
#              001xb - SD boot via uSDHC
#              10xxb - eMMC/MMC boot via uSDHC
#              01xxb - SLC NAND boot via SEMC
#              0001b - Parallel NOR boot via SEMC
#              11xxb - Serial NAND boot via FlexSPI
proc get_boot_device {} {
    set SRC_SBMR1 [ mrw 0x400F8004 ]
    set bootdevice [expr {($SRC_SBMR1 & 0x000000F0) >> 4} ]
    return $bootdevice
}

proc get_reset_vector {} {
    global FLASH_MEMORY_BASE
    set MAX_FLASH_MEMORY_SIZE 0x10000000
    
    set vector_table_addr [ mrw [expr {$FLASH_MEMORY_BASE + 0x1004} ] ]
    if { ($vector_table_addr < $FLASH_MEMORY_BASE) || ($vector_table_addr > ($FLASH_MEMORY_BASE + $MAX_FLASH_MEMORY_SIZE)) } {
        echo "Invalid vector table address: $vector_table_addr"
        return 0
    }
    
    set reset_vector [ mrw [expr {$vector_table_addr + 4}] ]
    return $reset_vector
}

# ------------------------------------------------------------------------------------------------------------------------------------------------


set RESET_INTO_BOOT_ROM 0

#The regular "reset halt" command on i.MXRT will stop the chip at the internal entry point in the boot ROM.
#At this point the internal bootloader has not initialized the peripherals set.
#So normally, we want to instead let the bootloader run and stop when it invokes the entry point of the main program.
#The 'reset_into_boot_rom' command controls this behavior.
#Usage: reset_into_boot_rom 0/1
proc reset_into_boot_rom { flag } {
    global RESET_INTO_BOOT_ROM
    set RESET_INTO_BOOT_ROM $flag
    if { $flag } {
        echo "'reset halt' will now try to stop in the boot ROM"
    } else {
        echo "'reset halt' will now try to stop at the entry point in FLASH"
    }
    
    return ""
}

set FLASH_MEMORY_BASE 0x60000000

proc init_reset { mode } {
    global RESET_INTO_BOOT_ROM
    global PENDING_ENTRY_POINT_ADDRESS
    set PENDING_ENTRY_POINT_ADDRESS 0
    
    if { ($mode eq "run") || $RESET_INTO_BOOT_ROM } {
        return
    }
    
    halt
    wait_halt 1000
    
    set bootmode [ get_boot_mode ]
    set bootdev [ get_boot_device ]
    
    if { $bootmode != 2 } {
        echo "Cannot reset into entry when boot mode is $bootmode"
        return
    }
    
    if { $bootdev != 0 } {
        echo "Cannot reset into entry when boot device is $bootdev"
        return
    }
    
    set entry_point [ get_reset_vector ]
    
    if { $entry_point == 0 } {
        echo "Cannot locate the reset vector in FLASH memory. Make sure FLASH is not empty and FlexSPI is initialized."
        return
    }
    
    set PENDING_ENTRY_POINT_ADDRESS $entry_point
}

#
# Only SWD and SPD supported
#
source [find target/swj-dp.tcl]

if { [info exists CPUTAPID] } {
    set _CPU_SWD_TAPID $CPUTAPID
} else {
    set _CPU_SWD_TAPID 0x0BD11477
}

swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap

if { [info exists WORKAREASIZE] } {
   set _WORKAREASIZE $WORKAREASIZE
} else {
   set _WORKAREASIZE 0x4000
}

$_TARGETNAME configure -work-area-phys 0x20200000 \
                       -work-area-size $_WORKAREASIZE \
                       -work-area-backup 0
                       
$_TARGETNAME configure -event reset-deassert-post {
    global PENDING_ENTRY_POINT_ADDRESS
    set halt_timeout 1000
    
    if { $PENDING_ENTRY_POINT_ADDRESS } {
        wait_halt $halt_timeout
        
        set entry_point_hex [ format "0x%X" $PENDING_ENTRY_POINT_ADDRESS ]
        echo "Found entry point at $entry_point_hex. Setting a temporary breakpoint and resetting..."
        bp $entry_point_hex 2 hw

        resume      
        wait_halt $halt_timeout
        rbp $entry_point_hex        
    }
}                      

#Using SRST on i.MXRT devices will not get the chip to halt. Doing a system reset on the ARM Cortex level instead works as expected
cortex_m reset_config sysresetreq
reset_config none

#To support FLASH programming on i.MXRT, download the FLASH plugin from https://github.com/sysprogs/flash_drivers and adjust/uncomment the line below:
#flash bank imxrt plugin $FLASH_MEMORY_BASE 0 0 0 0 flash/IMXRT1050_HyperFLASH_ROMAPI.elf
#i.maxrt
if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
} else {
    set _CHIPNAME imxrt
}

source [find mem_helper.tcl]

# ---------------------------------------------- Auxiliary functions for accessing i.MXRT registers ----------------------------------------------


# SBMR2: Bit 25..24:
# BOOT_MODE[1:0]: 00b - Boot From Fuses
#                 01b - Serial Downloader
#                 10b - Internal Boot
#                 11b - Reserved
proc get_boot_mode {} {
    set SRC_SBMR2 [ mrw 0x400F801C ]
    set bootmode [ expr {($SRC_SBMR2 & 0x03000000) >> 24} ]
    return $bootmode
}

# Boot Device: 0000b - Serial NOR boot via FlexSPI
#              001xb - SD boot via uSDHC
#              10xxb - eMMC/MMC boot via uSDHC
#              01xxb - SLC NAND boot via SEMC
#              0001b - Parallel NOR boot via SEMC
#              11xxb - Serial NAND boot via FlexSPI
proc get_boot_device {} {
    set SRC_SBMR1 [ mrw 0x400F8004 ]
    set bootdevice [expr {($SRC_SBMR1 & 0x000000F0) >> 4} ]
    return $bootdevice
}

proc get_reset_vector {} {
    global FLASH_MEMORY_BASE
    set MAX_FLASH_MEMORY_SIZE 0x10000000
    
    set vector_table_addr [ mrw [expr {$FLASH_MEMORY_BASE + 0x1004} ] ]
    if { ($vector_table_addr < $FLASH_MEMORY_BASE) || ($vector_table_addr > ($FLASH_MEMORY_BASE + $MAX_FLASH_MEMORY_SIZE)) } {
        echo "Invalid vector table address: $vector_table_addr"
        return 0
    }
    
    set reset_vector [ mrw [expr {$vector_table_addr + 4}] ]
    return $reset_vector
}

# ------------------------------------------------------------------------------------------------------------------------------------------------


set RESET_INTO_BOOT_ROM 0

#The regular "reset halt" command on i.MXRT will stop the chip at the internal entry point in the boot ROM.
#At this point the internal bootloader has not initialized the peripherals set.
#So normally, we want to instead let the bootloader run and stop when it invokes the entry point of the main program.
#The 'reset_into_boot_rom' command controls this behavior.
#Usage: reset_into_boot_rom 0/1
proc reset_into_boot_rom { flag } {
    global RESET_INTO_BOOT_ROM
    set RESET_INTO_BOOT_ROM $flag
    if { $flag } {
        echo "'reset halt' will now try to stop in the boot ROM"
    } else {
        echo "'reset halt' will now try to stop at the entry point in FLASH"
    }
    
    return ""
}

set FLASH_MEMORY_BASE 0x60000000

proc init_reset { mode } {
    global RESET_INTO_BOOT_ROM
    global PENDING_ENTRY_POINT_ADDRESS
    set PENDING_ENTRY_POINT_ADDRESS 0
    
    if { ($mode eq "run") || $RESET_INTO_BOOT_ROM } {
        return
    }
    
    halt
    wait_halt 1000
    
    set bootmode [ get_boot_mode ]
    set bootdev [ get_boot_device ]
    
    if { $bootmode != 2 } {
        echo "Cannot reset into entry when boot mode is $bootmode"
        return
    }
    
    if { $bootdev != 0 } {
        echo "Cannot reset into entry when boot device is $bootdev"
        return
    }
    
    set entry_point [ get_reset_vector ]
    
    if { $entry_point == 0 } {
        echo "Cannot locate the reset vector in FLASH memory. Make sure FLASH is not empty and FlexSPI is initialized."
        return
    }
    
    set PENDING_ENTRY_POINT_ADDRESS $entry_point
}

#
# Only SWD and SPD supported
#
source [find target/swj-dp.tcl]

if { [info exists CPUTAPID] } {
    set _CPU_SWD_TAPID $CPUTAPID
} else {
    set _CPU_SWD_TAPID 0x0BD11477
}

swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap

if { [info exists WORKAREASIZE] } {
   set _WORKAREASIZE $WORKAREASIZE
} else {
   set _WORKAREASIZE 0x4000
}

$_TARGETNAME configure -work-area-phys 0x20200000 \
                       -work-area-size $_WORKAREASIZE \
                       -work-area-backup 0
                       
$_TARGETNAME configure -event reset-deassert-post {
    global PENDING_ENTRY_POINT_ADDRESS
    set halt_timeout 1000
    
    if { $PENDING_ENTRY_POINT_ADDRESS } {
        wait_halt $halt_timeout
        
        set entry_point_hex [ format "0x%X" $PENDING_ENTRY_POINT_ADDRESS ]
        echo "Found entry point at $entry_point_hex. Setting a temporary breakpoint and resetting..."
        bp $entry_point_hex 2 hw

        resume      
        wait_halt $halt_timeout
        rbp $entry_point_hex        
    }
}                      

#Using SRST on i.MXRT devices will not get the chip to halt. Doing a system reset on the ARM Cortex level instead works as expected
cortex_m reset_config sysresetreq
reset_config none

#To support FLASH programming on i.MXRT, download the FLASH plugin from https://github.com/sysprogs/flash_drivers and adjust/uncomment the line below:
#flash bank imxrt plugin $FLASH_MEMORY_BASE 0 0 0 0 flash/IMXRT1050_HyperFLASH_ROMAPI.elf