square / pylink

Python Library for device debugging/programming via J-Link
https://pylink.readthedocs.io/en/latest/
Other
346 stars 127 forks source link

nRF5340 flashing issue: Failed to prepare for programming. Could not preserve target memory. #177

Open vpmdt opened 1 year ago

vpmdt commented 1 year ago

Hi, struggling with flashing nRF5340. If I flash it manually with J-Flash Lite, first NET then APP core, it works fine. I need to flash both cores with no reset between them, NET and APP respectively, because of the readback protection.

jlk = pylink.JLink()
jlk.open(serial_no=int(jlink_sn))
jlk.set_tif(pylink.enums.JLinkInterfaces.SWD)
....
....
    jlk.connect(chip_name='nrf5340_xxaa_net', verbose=True)
    jlk.flash(binstr_obj1, min_addr1)

    jlk.connect(chip_name='nrf5340_xxaa_app', verbose=True)
    jlk.flash(binstr_obj2, min_addr2)

first flash is succesfully done, but after second flash I get error: Failed to prepare for programming. Could not preserve target memory.

Any ideas? Thanks!!

hkpeprah commented 1 year ago

Do you have any more logs? Is it possible that the chip is not being properly held in reset?

vpmdt commented 1 year ago

I'm trying more things to get it working, so here is the only succesful setup for flashing:

  1. First the manual flash of merged hex (net and app core) is done via nRF Programmer
  2. Then I can run the script which is
jlk = pylink.JLink()
jlk.open(serial_no=int(jlink_sn))
jlk.set_tif(pylink.enums.JLinkInterfaces.SWD)

# SWDSelect
jlk.coresight_configure()

# SWDWriteDP 1 0x50000000
jlk.coresight_write(reg=1, data=0x50000000, ap=False)

# SWDWriteDP 2 0x020000F0
jlk.coresight_write(reg=2, data=0x020000F0, ap=False)

# SWDReadAP 3
jlk.coresight_read(reg=3, ap=True)
time.sleep(0.5)

# SWDReadAP 3
jlk.coresight_read(reg=3, ap=True)
time.sleep(0.5)

# SWDWriteDP 2 0x02000000
jlk.coresight_write(reg=2, data=0x02000000, ap=False)

# SWDWriteAP 1 1
jlk.coresight_write(reg=1, data=1, ap=True)

# SWDReadAP 2
jlk.coresight_read(reg=2, ap=True)
time.sleep(0.5)

# SWDReadAP 2
jlk.coresight_read(reg=2, ap=True)
time.sleep(0.5)

# SWDReadAP 2
jlk.coresight_read(reg=2, ap=True)
time.sleep(0.5)

# SWDWriteDP 2 0x03000000
jlk.coresight_write(reg=2, data=0x03000000, ap=False)

# SWDWriteAP 1 1
jlk.coresight_write(reg=1, data=1, ap=True)

# SWDReadAP 2
jlk.coresight_read(reg=2, ap=True)
time.sleep(0.5)

# SWDReadAP 2
jlk.coresight_read(reg=2, ap=True)
time.sleep(0.5)

# SWDReadAP 2
jlk.coresight_read(reg=2, ap=True)
time.sleep(0.5)

jlk.connect(chip_name='nrf5340_xxaa_net', verbose=True)
jlk.flash(binstr_obj1, min_addr1)

jlk.connect(chip_name='nrf5340_xxaa_app', verbose=True)
jlk.flash(binstr_obj2, min_addr2)

If the chip is fully erased it fails as described in my first comment - it fails when the second flash is executed (when the app core is being flashed). Let me know if you need other information. Thank you!

PS: the sequence of reading and writing to the DAP registers is basicaly this: https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/allowing-debugger-access-to-an-nrf5340 without that I can not even connect to the target. If this sequence is skipped, I get error:

pylink.errors.JLinkException: Could not find supported CPU. Could not find core in Coresight setup

hkpeprah commented 1 year ago

I would try playing around with the reset strategies here: https://pylink.readthedocs.io/en/latest/pylink.html#pylink.jlink.JLink.set_reset_strategy

It's possible that the core starts running after you flash the first asset, and changing the reset strategy might happen. There's also the set_reset_pin_high() and set_reset_pin_low() APIs where you can manually hold the core in reset while you do your flashing.

enjeru15 commented 11 months ago

Hi, has this been resolved already?

ahmedyahia3393 commented 4 months ago

Hi While flashing a hex file, I have the same error but using nrf52840 and Segger j-link. you can see the attached photo as a reference. I tried resetting the chip and erasing it beforehand, but nothing changed. Thanks.

flashing error
hkpeprah commented 4 months ago

Could you try a different reset strategy? I don't have an NRF5340 to play around with, unfortunately.

juhhov commented 2 weeks ago

Pylink does not allow connecting to second core due to this https://github.com/square/pylink/blob/0b3e8ca8768725b27b1fd58df71f7110084ee6fb/pylink/jlink.py#L1156C1-L1159C52. Once first core is connected to the attempt to connect to second core is refused silently.

hkpeprah commented 2 weeks ago

Pylink does not allow connecting to second core due to this https://github.com/square/pylink/blob/0b3e8ca8768725b27b1fd58df71f7110084ee6fb/pylink/jlink.py#L1156C1-L1159C52. Once first core is connected to the attempt to connect to second core is refused silently.

Interesting. Do you have example code? Is the second Device = call supposed to fail? Maybe we're missing a disconnect, or need to instantiate another instance and tear down the existing one.

juhhov commented 2 weeks ago

Yes, pylink is missing disconnect API (or something similar) to disconnect target connection. Adding such API might be the least effort?

If exec_command and straight DLL access is used to bypass pylink API's at least the flashing of second core seems to succeed.

jlink.exec_command('Device = NRF5340_XXAA_NET')
jlink._dll.JLINKARM_Connect()
hkpeprah commented 1 week ago

I will take a look; this is something I over-looked as I haven't worked on multi-CPU ARM chips, though if you're able to come up with something that you can test against your setup, I also welcome the patch.