Search code examples
gdblpccortex-mopenocd

Configuring secondary core in OpenOCD


I'm having trouble using OpenOCD to program and debug LPC4357 microcontroller. This chip has a Cortex M4 core and a secondary Cortex M0 core. This is OpenOCD config I'm using:

source [find target/swj-dp.tcl]

adapter_khz 1000

if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
} else {
    set _CHIPNAME lpc43xx
}

if { [info exists M4_JTAG_TAPID] } {
    set _M4_JTAG_TAPID $M4_JTAG_TAPID
} else {
    set _M4_JTAG_TAPID 0x4ba00477
}

if { [info exists M4_SWD_TAPID] } {
    set _M4_SWD_TAPID $M4_SWD_TAPID
} else {
    set _M4_SWD_TAPID 0x2ba01477
}

if { [using_jtag] } {
    set _M4_TAPID $_M4_JTAG_TAPID
} {
    set _M4_TAPID $_M4_SWD_TAPID
}

if { [info exists M0_JTAG_TAPID] } {
    set _M0_JTAG_TAPID $M0_JTAG_TAPID
} else {
    set _M0_JTAG_TAPID 0x0ba01477
}

swj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M4_JTAG_TAPID
swj_newdap $_CHIPNAME m0 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M0_JTAG_TAPID

target create $_CHIPNAME.m0 cortex_m -chain-position $_CHIPNAME.m0
target create $_CHIPNAME.m4 cortex_m -chain-position $_CHIPNAME.m4

set _WORKAREASIZE 0x2000
$_CHIPNAME.m4 configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE

set _FLASHNAME $_CHIPNAME.flash
flash bank flashA lpc2000 0x1a000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 107000 calc_checksum
flash bank flashB lpc2000 0x1b000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 107000 calc_checksum

cortex_m reset_config vectreset

Trying to use GDB's load command to write something to internal flash will give following error:

Error: timed out while waiting for target halted
TARGET: lpc43xx.m0 - Not halted
in procedure 'reset'
in procedure 'ocd_bouncer'

in procedure 'reset'

Error: Target not halted
Error: failed erasing sectors 0 to 3
Error: flash_erase returned -304
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x41000000 pc: 0x10402d5e msp: 0x10089c70, semihosting
Info : Halt timed out, wake up GDB.

Now I suspect the problem is that OpenOCD thinks it has to halt the M0 core before writing to flash, and the M0 core is not responding to halt request.

The reason for this is that M0 core is not even running and therefore cannot be halted. Its reset and clock signals are controlled by M4 core and they are enabled only later in boot sequence.

Is there a way to tell OpenOCD that M0 core is not available until after it's enabled by M4 firmware?


Solution

  • Subtle:

    target create $_CHIPNAME.m0 cortex_m -chain-position $_CHIPNAME.m0
    target create $_CHIPNAME.m4 cortex_m -chain-position $_CHIPNAME.m4`
    

    Try swapping these lines. The first created target - M0 - seems to be the default one.

    You could also use the targets $_CHIPNAME.m4 command - note the plural in the command.