pyocd / pyOCD

Open source Python library for programming and debugging Arm Cortex-M microcontrollers
https://pyocd.io
Apache License 2.0
1.1k stars 477 forks source link

Regression erasing and programming NXP Kinetis targets #1123

Open Timmmm opened 3 years ago

Timmmm commented 3 years ago

I have a Dip Dap and I'm trying to use it to program the bootloader of a FRDM-K22F as described here.

I have connected the SWD IO, CLK and 3.3V/GND to the board, and install libusb-1.0. However some weird things happen. When I run pyocd list it says:

> pyocd list
  #   Probe                    Unique ID
---------------------------------------------------------------------------------
  0   Seeed Tiny BLE [nrf51]   9012000004a22ae300000000000000000000000097969902

That is definitely wrong, but maybe it doesn't matter.

Then when I try to flash it:

>pyocd flash "Downloads\0244_k20dx_bl_0x8000.bin" -t k20d50m
0001876:CRITICAL:__main__:No ACK received
Traceback (most recent call last):
  File "c:\python38\lib\site-packages\pyocd\probe\cmsis_dap_probe.py", line 312, in read_dp
    result = self._link.read_reg(reg_id, now=now)
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 899, in read_reg
    return read_reg_cb()
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 893, in read_reg_cb
    res = transfer.get_result()
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 147, in get_result
    self.daplink.flush()
  File "c:\python38\lib\site-packages\pyocd\utility\concurrency.py", line 28, in _locking
    return func(self, *args, **kwargs)
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 713, in flush
    self._read_packet()
  File "c:\python38\lib\site-packages\pyocd\utility\concurrency.py", line 28, in _locking
    return func(self, *args, **kwargs)
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 978, in _read_packet
    decoded_data = cmd.decode_data(raw_data)
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 453, in decode_data
    data = self._decode_transfer_block_data(data)
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 422, in _decode_transfer_block_data
    self._check_response(data[3])
  File "c:\python38\lib\site-packages\pyocd\probe\pydapaccess\dap_access_cmsis_dap.py", line 345, in _check_response
    raise DAPAccessIntf.TransferError("No ACK received")
pyocd.probe.pydapaccess.dap_access_api.DAPAccessIntf.TransferError: No ACK received

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 402, in run
    self._COMMANDS[self._args.cmd](self)
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 572, in do_flash
    with session:
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 339, in __enter__
    self.open()
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 457, in open
    self._board.init()
  File "c:\python38\lib\site-packages\pyocd\board\board.py", line 85, in init
    self.target.init()
  File "c:\python38\lib\site-packages\pyocd\core\soc_target.py", line 117, in init
    seq.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 213, in invoke
    resultSequence.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 208, in invoke
    resultSequence = call()
  File "c:\python38\lib\site-packages\pyocd\coresight\dap.py", line 376, in _connect
    connector.connect(self._protocol)
  File "c:\python38\lib\site-packages\pyocd\coresight\dap.py", line 166, in connect
    self._connect_dp(protocol)
  File "c:\python38\lib\site-packages\pyocd\coresight\dap.py", line 206, in _connect_dp
    self._idr = self.read_idr()
  File "c:\python38\lib\site-packages\pyocd\coresight\dap.py", line 233, in read_idr
    dpidr = self._probe.read_dp(DP_IDR, now=True)
  File "c:\python38\lib\site-packages\pyocd\probe\cmsis_dap_probe.py", line 315, in read_dp
    six.raise_from(self._convert_exception(error), error)
  File "<string>", line 3, in raise_from
pyocd.core.exceptions.TransferError: No ACK received

Any idea why this is?

Timmmm commented 3 years ago

Ah I decided to try updating the firmware on the DipDap (instructions below for random travellers since it's super confusing). I get a bit further but now it can't erase the chip.

C:\Users\Tim>pyocd list
  #   Probe           Unique ID
------------------------------------------------------------------------
  0   ARM CMSIS-DAP   7401000004a22ae300000000000000000000000097969902

C:\Users\Tim>pyocd flash "Downloads\0244_k20dx_bl_0x8000.bin" -t k20d50m
0003111:WARNING:target_kinetis:K20D50M in secure state: will try to unlock via mass erase
0014064:ERROR:target_kinetis:Mass erase timeout waiting for Flash Mass Erase Ack to set
0014068:ERROR:target_kinetis:K20D50M: mass erase failed
0014073:CRITICAL:__main__:unable to unlock device
Traceback (most recent call last):
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 402, in run
    self._COMMANDS[self._args.cmd](self)
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 572, in do_flash
    with session:
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 339, in __enter__
    self.open()
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 457, in open
    self._board.init()
  File "c:\python38\lib\site-packages\pyocd\board\board.py", line 85, in init
    self.target.init()
  File "c:\python38\lib\site-packages\pyocd\core\soc_target.py", line 117, in init
    seq.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 213, in invoke
    resultSequence.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 208, in invoke
    resultSequence = call()
  File "c:\python38\lib\site-packages\pyocd\target\family\target_kinetis.py", line 159, in check_flash_security
    raise exceptions.TargetError("unable to unlock device")
pyocd.core.exceptions.TargetError: unable to unlock device

I definitely haven't ever set any security bits.


DipDap update instructions.

  1. Go to here
  2. Download one of the prebuild images. It doesn't really matter which one! The name of the chip in the prebuilt images is just the target device that will be supported via the drag and drop interface, but for CMSIS-DAP/pyOCD it doesn't matter.
  3. Unplug the board, hold the button on it down, plug it back in again.
  4. Delete the firmware.bin on the CRP-DISABLED drive and copy the file you downloaded onto it.
  5. Unplug it and plug it in again.
Timmmm commented 3 years ago

I tried another identical board and it gets a bit further but just seems to get stuck when I try to erase or flash it (I realised I was using the wrong target btw, but I still got the above output with -t k22f):

C:\Users\Tim>pyocd flash "Downloads\0244_k20dx_bl_0x8000.bin" -t k22f -vv
0001640:DEBUG:pemicro:Opened PEMicro library: c:\python38\lib\site-packages\pypemicro\libs\Windows\unitacmp-64.dll
0001709:DEBUG:session:Project directory: C:\Users\Tim
0001713:INFO:board:Target type is k22f
0001718:DEBUG:dap_access_cmsis_dap:CMSIS-DAP probe 7401000004a22ae300000000000000000000000097969902 protocol version: 1.0.0
0001726:DEBUG:sequencer:Running task load_svd
0001728:DEBUG:sequencer:Running task pre_connect
0001728:DEBUG:sequencer:Running task dp_init
0001747:DEBUG:sequencer:Running task lock_probe
0001748:DEBUG:sequencer:Running task get_probe_capabilities
0001750:DEBUG:sequencer:Running task connect
0001758:DEBUG:dap:Default wire protocol selected; using SWD
0001762:DEBUG:swj:Sending deprecated SWJ sequence to select SWD
0001771:INFO:dap:DP IDR = 0x2ba01477 (v1 rev2)
0001771:DEBUG:sequencer:Running task clear_sticky_err
0001773:DEBUG:sequencer:Running task power_up_debug
0001777:DEBUG:sequencer:Running task check_version
0001777:DEBUG:sequencer:Running task unlock_probe
0001778:DEBUG:sequencer:Running task create_discoverer
0001779:DEBUG:sequencer:Running task discovery
0001780:DEBUG:sequencer:Running task find_aps
0001796:DEBUG:sequencer:Running task create_aps
0001796:DEBUG:sequencer:Running task create_ap.0
0001801:INFO:ap:AHB-AP#0 IDR = 0x24770011 (AHB-AP var1 rev2)
0001831:DEBUG:ap:AHB-AP#0 default HPROT=3 HNONSEC=0
0001834:DEBUG:ap:AHB-AP#0 implemented HPROT=3 HNONSEC=0
0001837:DEBUG:sequencer:Running task create_ap.1
0001840:INFO:ap:AP#1 IDR = 0x001c0000 (AP var0 rev0)
0001840:DEBUG:sequencer:Running task check_mdm_ap_idr
0001842:DEBUG:target_kinetis:MDM-AP version 0
0001842:DEBUG:sequencer:Running task check_flash_security
0001876:INFO:target_kinetis:K22F not in secure state
0001877:DEBUG:sequencer:Running task find_components
0001877:DEBUG:sequencer:Running task init_ap.0
0002073:INFO:rom_table:AHB-AP#0 Class 0x1 ROM table #0 @ 0xe00ff000 (designer=43b part=4c4)
0002095:INFO:rom_table:[0]<e000e000:SCS-M3 class=14 designer=43b part=000>
0002101:INFO:rom_table:[1]<e0001000:DWT class=14 designer=43b part=002>
0002107:INFO:rom_table:[2]<e0002000:FPB class=14 designer=43b part=003>
0002113:INFO:rom_table:[3]<e0000000:ITM class=14 designer=43b part=001>
0002119:INFO:rom_table:[4]<e0040000:TPIU-M4 class=9 designer=43b part=9a1 devtype=11 archid=0000 devid=ca0:0:0>
0002119:DEBUG:sequencer:Running task create_cores
0002119:DEBUG:discovery:Creating SCS-M3 component
0002123:INFO:cortex_m:CPU core #0 is Cortex-M4 r0p1
0002127:DEBUG:sequencer:Running task create_components
0002128:DEBUG:discovery:Creating DWT component
0002132:INFO:dwt:4 hardware watchpoints
0002133:DEBUG:discovery:Creating FPB component
0002136:INFO:fpb:6 hardware breakpoints, 4 literal comparators
0002137:DEBUG:fpb:fpb has been disabled
0002139:DEBUG:discovery:Creating ITM component
0002145:DEBUG:discovery:Creating TPIU-M4 component
0002149:DEBUG:sequencer:Running task check_for_cores
0002150:DEBUG:sequencer:Running task halt_on_connect
0002150:DEBUG:cortex_m:halting core 0
0002152:DEBUG:sequencer:Running task post_connect
0002153:DEBUG:sequencer:Running task post_connect_hook
0002154:DEBUG:sequencer:Running task create_flash
0002154:DEBUG:sequencer:Running task notify
0002156:DEBUG:cortex_m:halting core 0
0002158:DEBUG:cortex_m:set reset catch, core 0
0002159:DEBUG:cortex_m:halting core 0
0002163:DEBUG:cortex_m:reset, core 0, type=SW_SYSRESETREQ
0002179:DEBUG:cortex_m:clear reset catch, core 0
0002265:DEBUG:cortex_m:resuming core 0
0002265:DEBUG:manager:added=[] removed=[]
0002268:DEBUG:manager:bps after flush={}
C:\Users\Tim>pyocd erase --chip -t k22f -vv
0001668:DEBUG:pemicro:Opened PEMicro library: c:\python38\lib\site-packages\pypemicro\libs\Windows\unitacmp-64.dll
0001747:DEBUG:session:Project directory: C:\Users\Tim
0001751:INFO:board:Target type is k22f
0001755:DEBUG:dap_access_cmsis_dap:CMSIS-DAP probe 7401000004a22ae300000000000000000000000097969902 protocol version: 1.0.0
0001762:DEBUG:sequencer:Running task load_svd
0001764:DEBUG:sequencer:Running task pre_connect
0001765:DEBUG:sequencer:Running task dp_init
0001788:DEBUG:sequencer:Running task lock_probe
0001788:DEBUG:sequencer:Running task get_probe_capabilities
0001790:DEBUG:sequencer:Running task connect
0001802:DEBUG:dap:Default wire protocol selected; using SWD
0001805:DEBUG:swj:Sending deprecated SWJ sequence to select SWD
0001816:INFO:dap:DP IDR = 0x2ba01477 (v1 rev2)
0001818:DEBUG:sequencer:Running task clear_sticky_err
0001818:DEBUG:sequencer:Running task power_up_debug
0001823:DEBUG:sequencer:Running task check_version
0001823:DEBUG:sequencer:Running task unlock_probe
0001825:DEBUG:sequencer:Running task create_discoverer
0001827:DEBUG:sequencer:Running task discovery
0001828:DEBUG:sequencer:Running task find_aps
0001845:DEBUG:sequencer:Running task create_aps
0001845:DEBUG:sequencer:Running task create_ap.0
0001875:INFO:ap:AHB-AP#0 IDR = 0x24770011 (AHB-AP var1 rev2)
0001881:DEBUG:ap:AHB-AP#0 default HPROT=3 HNONSEC=0
0001886:DEBUG:ap:AHB-AP#0 implemented HPROT=3 HNONSEC=0
0001890:DEBUG:sequencer:Running task create_ap.1
0001894:INFO:ap:AP#1 IDR = 0x001c0000 (AP var0 rev0)
0001896:DEBUG:sequencer:Running task check_mdm_ap_idr
0001896:DEBUG:target_kinetis:MDM-AP version 0
0001897:DEBUG:sequencer:Running task check_flash_security
0002046:INFO:target_kinetis:K22F not in secure state
0002062:DEBUG:sequencer:Running task find_components
0002078:DEBUG:sequencer:Running task init_ap.0
0002141:INFO:rom_table:AHB-AP#0 Class 0x1 ROM table #0 @ 0xe00ff000 (designer=43b part=4c4)
0002151:INFO:rom_table:[0]<e000e000:SCS-M3 class=14 designer=43b part=000>
0002158:INFO:rom_table:[1]<e0001000:DWT class=14 designer=43b part=002>
0002165:INFO:rom_table:[2]<e0002000:FPB class=14 designer=43b part=003>
0002171:INFO:rom_table:[3]<e0000000:ITM class=14 designer=43b part=001>
0002177:INFO:rom_table:[4]<e0040000:TPIU-M4 class=9 designer=43b part=9a1 devtype=11 archid=0000 devid=ca0:0:0>
0002178:DEBUG:sequencer:Running task create_cores
0002178:DEBUG:discovery:Creating SCS-M3 component
0002181:INFO:cortex_m:CPU core #0 is Cortex-M4 r0p1
0002185:DEBUG:sequencer:Running task create_components
0002186:DEBUG:discovery:Creating DWT component
0002190:INFO:dwt:4 hardware watchpoints
0002192:DEBUG:discovery:Creating FPB component
0002195:INFO:fpb:6 hardware breakpoints, 4 literal comparators
0002196:DEBUG:fpb:fpb has been disabled
0002198:DEBUG:discovery:Creating ITM component
0002204:DEBUG:discovery:Creating TPIU-M4 component
0002208:DEBUG:sequencer:Running task check_for_cores
0002208:DEBUG:sequencer:Running task halt_on_connect
0002209:DEBUG:cortex_m:halting core 0
0002212:DEBUG:sequencer:Running task post_connect
0002212:DEBUG:sequencer:Running task post_connect_hook
0002212:DEBUG:sequencer:Running task create_flash
0002213:DEBUG:sequencer:Running task notify
0002213:INFO:eraser:Erasing chip...
0002214:DEBUG:cortex_m:halting core 0
0002217:DEBUG:cortex_m:set reset catch, core 0
0002217:DEBUG:cortex_m:halting core 0
0002222:DEBUG:cortex_m:reset, core 0, type=SW_SYSRESETREQ
0002240:DEBUG:cortex_m:clear reset catch, core 0
0002326:DEBUG:cortex_m:resuming core 0
0002326:DEBUG:manager:added=[] removed=[]
0002329:DEBUG:manager:bps after flush={}

Wish I hadn't lost my Segger :-(

Timmmm commented 3 years ago

Uhmm....

C:\Users\Tim>pyocd erase --chip -t k22f -vv
0001662:DEBUG:pemicro:Opened PEMicro library: c:\python38\lib\site-packages\pypemicro\libs\Windows\unitacmp-64.dll
Waiting for a debug probe to be connected...
0002351:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0002938:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0003535:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0004100:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0004696:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0005251:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0005817:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0006408:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0006981:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0007544:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0008144:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0008712:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0009316:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0009886:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0010453:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0011051:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0011645:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0012233:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0012803:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0013365:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0013937:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0014535:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
0015133:DEBUG:pemicro:Opened PEMicro library: unitacmp-64.dll
Timmmm commented 3 years ago

Ok I think the main issue is the security bit:

C:\Users\Tim>pyocd flash "Downloads\0244_k20dx_bl_0x8000.bin" -t k22f -vv
0001738:DEBUG:pemicro:Opened PEMicro library: c:\python38\lib\site-packages\pypemicro\libs\Windows\unitacmp-64.dll
0001819:DEBUG:session:Project directory: C:\Users\Tim
0001823:INFO:board:Target type is k22f
0001827:DEBUG:dap_access_cmsis_dap:CMSIS-DAP probe 7401000004a22ae300000000000000000000000097969902 protocol version: 1.0.0
0001836:DEBUG:sequencer:Running task load_svd
0001838:DEBUG:sequencer:Running task pre_connect
0001838:DEBUG:sequencer:Running task dp_init
0001856:DEBUG:sequencer:Running task lock_probe
0001857:DEBUG:sequencer:Running task get_probe_capabilities
0001858:DEBUG:sequencer:Running task connect
0001870:DEBUG:dap:Default wire protocol selected; using SWD
0001872:DEBUG:swj:Sending deprecated SWJ sequence to select SWD
0001883:INFO:dap:DP IDR = 0x2ba01477 (v1 rev2)
0001883:DEBUG:sequencer:Running task clear_sticky_err
0001885:DEBUG:sequencer:Running task power_up_debug
0001888:DEBUG:sequencer:Running task check_version
0001889:DEBUG:sequencer:Running task unlock_probe
0001891:DEBUG:sequencer:Running task create_discoverer
0001891:DEBUG:sequencer:Running task discovery
0001893:DEBUG:sequencer:Running task find_aps
0001910:DEBUG:sequencer:Running task create_aps
0001911:DEBUG:sequencer:Running task create_ap.0
0001940:INFO:ap:AHB-AP#0 IDR = 0x24770011 (AHB-AP var1 rev2)
0001943:DEBUG:ap:AHB-AP#0 default HPROT=3 HNONSEC=0
0001947:DEBUG:ap:AHB-AP#0 implemented HPROT=3 HNONSEC=0
0001950:DEBUG:sequencer:Running task create_ap.1
0001955:INFO:ap:AP#1 IDR = 0x001c0000 (AP var0 rev0)
0001955:DEBUG:sequencer:Running task check_mdm_ap_idr
0001956:DEBUG:target_kinetis:MDM-AP version 0
0001957:DEBUG:sequencer:Running task check_flash_security
0002769:DEBUG:target_kinetis:Access test failed with fault
0002842:WARNING:target_kinetis:K22F in secure state: will try to unlock via mass erase
0013087:ERROR:target_kinetis:Mass erase timeout waiting for Flash Mass Erase Ack to set
0015623:ERROR:target_kinetis:K22F: mass erase failed
0015623:DEBUG:session:uninit session <pyocd.core.session.Session object at 0x0000017055863400>
0015629:DEBUG:hidapi_backend:closing interface
0015629:CRITICAL:__main__:unable to unlock device
Traceback (most recent call last):
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 402, in run
    self._COMMANDS[self._args.cmd](self)
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 572, in do_flash
    with session:
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 339, in __enter__
    self.open()
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 457, in open
    self._board.init()
  File "c:\python38\lib\site-packages\pyocd\board\board.py", line 85, in init
    self.target.init()
  File "c:\python38\lib\site-packages\pyocd\core\soc_target.py", line 117, in init
    seq.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 213, in invoke
    resultSequence.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 208, in invoke
    resultSequence = call()
  File "c:\python38\lib\site-packages\pyocd\target\family\target_kinetis.py", line 159, in check_flash_security
    raise exceptions.TargetError("unable to unlock device")
pyocd.core.exceptions.TargetError: unable to unlock device

And actually now that I think about it the original target was probably right because I'm flashing the interface chip. That doesn't work either though

0001963:DEBUG:sequencer:Running task check_flash_security
0004279:WARNING:target_kinetis:K20D50M in secure state: will try to unlock via mass erase
0014573:ERROR:target_kinetis:Mass erase timeout waiting for Flash Mass Erase Ack to set
0014577:ERROR:target_kinetis:K20D50M: mass erase failed
0014577:DEBUG:session:uninit session <pyocd.core.session.Session object at 0x0000012339293A60>
0014582:DEBUG:hidapi_backend:closing interface
0014582:CRITICAL:__main__:unable to unlock device

Pretty close to throwing these in the bin...

flit commented 3 years ago

Hi there 😄

Kinetis devices have flash security enabled by default, with fully erased flash. The unlock process involves programming a bit in the Flash Config Field at address 0x400 to disable security.

The repeated PEMicro logs are happening because the PEMicro probe interface in pyocd is loading the PEMicro driver shared library to look for connected PEMicro probes.

Since you're programming the interface chip on the FRDM-K22F, you need to use the k20d50m target type.

I have seen cases where mass erase times out before, but never got to the bottom of it, i.e., whether it was a real issue in the chip or something in pyocd.

Do you know what firmware was on the K20 interface chip to begin with? Mostly I'm interested if it was the PEMicro firmware that shipped on some FRDM boards, because this firmware permanently locks the flash which could explain the issue.

When I have some time, I will try updating the interface firmware on a FRDM-K22F to replicate your situation. I can't guarantee how quickly this will be, but I'll try to find time in the next couple days.

(Fyi, there is a much newer release of the DAPLink firmware: 0254. Download the release .zip and use the 0254_k20dx_frdmk22f_0x8000.bin binary inside.)

Timmmm commented 3 years ago

Do you know what firmware was on the K20 interface chip to begin with? Mostly I'm interested if it was the PEMicro firmware that shipped on some FRDM boards, because this firmware permanently locks the flash which could explain the issue.

I have no idea, but I did buy these like 5 years ago, so I'd guess so.

(Fyi, there is a much newer release of the DAPLink firmware: 0254. Download the release .zip and use the 0254_k20dx_frdmk22f_0x8000.bin binary inside.)

Ah I updated the DipDap with this newer firmware (using one of the 0254_lcp11u35_... .bin files) but it didn't make any difference. However I did notice that a sporadic error I had been getting actually gets further along than the previous traces. Sometimes I get this output which says not in secure state, but then fails for some other reason.

...
0001961:DEBUG:sequencer:Running task check_flash_security
0002464:INFO:target_kinetis:K20D50M not in secure state
0002464:DEBUG:sequencer:Running task find_components
0002467:DEBUG:sequencer:Running task init_ap.0
0002473:WARNING:ap:Skipping CoreSight discovery for AHB-AP#0 because it is disabled
0002473:DEBUG:sequencer:Running task create_cores
0002474:DEBUG:sequencer:Running task create_components
0002475:DEBUG:sequencer:Running task check_for_cores
0002478:DEBUG:session:uninit session <pyocd.core.session.Session object at 0x00000202E5E13B20>
0002481:DEBUG:hidapi_backend:closing interface
0002481:CRITICAL:__main__:No cores were discovered!
Traceback (most recent call last):
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 402, in run
    self._COMMANDS[self._args.cmd](self)
  File "c:\python38\lib\site-packages\pyocd\__main__.py", line 572, in do_flash
    with session:
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 339, in __enter__
    self.open()
  File "c:\python38\lib\site-packages\pyocd\core\session.py", line 457, in open
    self._board.init()
  File "c:\python38\lib\site-packages\pyocd\board\board.py", line 85, in init
    self.target.init()
  File "c:\python38\lib\site-packages\pyocd\core\soc_target.py", line 117, in init
    seq.invoke()
  File "c:\python38\lib\site-packages\pyocd\utility\sequencer.py", line 208, in invoke
    resultSequence = call()
  File "c:\python38\lib\site-packages\pyocd\coresight\coresight_target.py", line 214, in check_for_cores
    raise exceptions.DebugError("No cores were discovered!")
pyocd.core.exceptions.DebugError: No cores were discovered!
Timmmm commented 3 years ago

It's actually random which happens - I added some code to print the status register while it is waiting for the board to erase and it seems to randomly become locked and unlocked (4 is the security bit):

0001982:DEBUG:sequencer:Running task check_flash_security
0002863:DEBUG:target_kinetis:Access test failed with fault
0003033:WARNING:target_kinetis:K20D50M in secure state: will try to unlock via mass erase
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
48
52
52
52
52
52
52
52
52
52
52
52
58
52
48
52
52
52
58
52
52
52
52
58
52
52
48
52
52
52
52
52
48
50
52
52
52
52
52
52
52
52
52
48
52

Very weird.

flit commented 3 years ago

The randomness implies that pyocd isn't managing the mass erase properly. The repeating lock/unlock usually happens when the device is repeatedly resetting due to no code in flash, as it boots, enters lockup state, then automatically resets and starts over. When the device first boots, it is always locked, then the flash controller inits and reads the flash config and unlocks if appropriate—normally this is super fast but on older devices it can take longer, but usually requires worn flash.

One thing you can try before I get a chance to debug it (assuming my FRDM-K22F behaves similarly!) is adding --connect=under-reset to the command line.

Timmmm commented 3 years ago

Same result I'm afraid. Don't spend too much time debugging this - I can probably just buy new boards that are better supported to be honest (I have one working K22F but simple mBed code doesn't seem to compile for it anyway :-/

flit commented 3 years ago

Thanks for trying it out. And I need to test it myself anyway. The Kinetis unlock support may have just become broken at some point recently. I do appreciate your reporting the trouble!

For the Mbed OS issue, I recommend creating an issue on https://github.com/ARMmbed/mbed-os/issues.

flit commented 3 years ago

Somehow I can't seem to find my FRDM-K22F anywhere. I'll try to reproduce with another board.

Timmmm commented 3 years ago

I can post a pre-broken one to you if you like, if you're in the UK? :-) By the way I wonder if this issue has something to do with PE Micro's Kinetis recovery utility - I saw it mentioned somewhere and it says something about recovering them where the reset pin is disabled or not connected. Not sure if that applies in this case though - it seems like it is resetting too much rather than not at all?

flit commented 3 years ago

Unfortunately, I'm in the US. 😀 But thanks for the offer!

You're right that it resets too much. For Kinetis devices without a boot ROM (or where the boot ROM is disabled), when there is no code in flash the device enters an infinite reset loop.

The device boots, but has no valid reset handler and so the CPU immediately enters lockup state. The CPU's in-lockup output signal is asserted, automatically triggering a hardware reset just like a watchdog. (This is a design property of the Kinetis devices. Some other Cortex-M MCUs have reset-on-lockup ability, but it's usually not enabled by default.)

flit commented 3 years ago

Small update: I've been able to reproduce programming failures on other Kinetis targets. Even the venerable K64F now fails test/flash_test.py. That's the price of not having a functional CI system, I suppose. (Although a new CI system is being built.)