Electronic – Flashing multi chips with JTAG using openocd

jtagmultiplexeropenocd

I'm newbie in this field. My task is I have to flash 6 devices with JTAG like the picture below. I'm currently success with flashing one device.
Can someone give me advice how to flash all 6 devices?
As I understand, when a device is being flashed, other will be in BYPASS mode, right? Then how can I control the devices? Just in case when flashing 6 devices and one fail, I can know which one is fail and flash it again.
If can, please explain to me like I'm a 5 years old boy would be very helpful.enter image description here

Edited 1:
These are my 2 config file.

source [find target/kinetis_generic.cfg]

$_TARGETNAME configure -event reset-init {}

flash bank pflash.0 kinetis 0x00000000 0x20000 0 4 $_TARGETNAME

proc program_device () {
 # halt the processor
 halt
 wait_halt
 # write file to flash memory
 poll
 flash probe 0
 flash write_image erase unlock "C:\\Users\\tung\\Desktop\\flash program\\OpenOCD-20170821\\sa2_can_195_init_boot&device.srec" 0x00000000
 #start execution of the program just downladed
 reset run
 #exit OpenOCD
 shutdown
}
init
reset init
program_device ()

and

source [find target/swj-dp.tcl]

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

if { [info exists ENDIAN] } {
    set _ENDIAN $ENDIAN
} else {
    set _ENDIAN little
}

if { [info exists CPUTAPID] } {
    set _CPUTAPID $CPUTAPID
} else {
    set _CPUTAPID 0x4ba00477
}


set _TARGETNAME $_CHIPNAME.cpu

swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu

$_CHIPNAME.cpu configure -event examine-start { puts "START..." ; }
$_CHIPNAME.cpu configure -event examine-end { puts "END..." ; }

# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq

Best Answer

When you set a device's IR to BYPASS, it will map a one bit register with no CAPTURE and UPDATE actions to DR.

The IR has a fixed length, let's assume two bit:

00 BOUNDARY-SCAN
01 IDCODE
10 PROGRAM
11 BYPASS

Further, assume that the PROGRAM chain has 16 bits, then you could program the first device with programming data p by sending (x means the bit is ignored)

IR
11 11 11 11 11 10

DR
x x x x x pppppppppppppppp

DR
x x x x x pppppppppppppppp

The second device can be addressed by sending

IR
11 11 11 11 10 11

DR
x x x x pppppppppppppppp x

and so on. So, you just add a fixed prefix and suffix to each IR and DR shifted.

With advanced controllers, it may be possible to program multiple devices in one go:

IR
10 10 11 11 11 11

DR
pppppppppppppppp pppppppppppppppp x x x x

That might save a bit of time, but AFAIK this is not implemented for OpenOCD.

Edit: Probably the easiest way to do this with OpenOCD is to describe the scan chain as it is:

for { set i 1 } { $i <= 6 } { incr i } {
    jtag newtap [string cat $_CHIPNAME $i] cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
    target create [string cat $_TARGETNAME $i] cortex_m -chain-position [string cat $_CHIPNAME $i].cpu
    [string cat $_CHIPNAME $i].cpu configure -event examine-start { puts "START..." ; }
    [string cat $_CHIPNAME $i].cpu configure -event examine-end { puts "END..." ; }
}
for { set i 1 } { $i <= 6 } { incr i } {
    flash bank pflash.$i kinetis 0x00000000 0x20000 0 4 [string cat $_CHIPNAME $i]
}

The jtag newtap command is the body of the swj_newdap function — your scan chain doesn't work with SWD, so you can inline that for clarity, and drop the source command at the top as that becomes unnecessary then.

The loop creates six targets, with numbers attached, and makes their flash available on separate banks. The flash bank setup is in a separate loop, so the scan chain configuration is correct already at this point (I believe no data is sent until the probe command, but better be safe). The flash banks command should show all of them.

You can then use another loop, or separate commands to write the individual flash files.