square / pylink

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

"Unspecified error" when connecting. JLinkExe works #206

Open alpevi opened 3 months ago

alpevi commented 3 months ago

Hello,

I have been experiencing the following issue lately. I use Pylink 1.2.0, JLink SDK 7.94 and the machine is a Raspberry Pi 4 (with Raspbian). The target hardware is a nRF52840 DK eval board:

Usually it works without any issue, I can connect, flash, erase and other common operations when using Pylink. Sometimes, for unknown reasons, the connect() method starts throwing the following exception (example of run commands):

Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pylink
>>> from pylink import JLink
>>> perico = JLink()
>>> perico.open()
>>> perico.set_tif(pylink.enums.JLinkInterfaces.SWD)
True
>>> perico.connect(chip_name='NRF52840_XXAA')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/devops_agent/_work/1/s/env/lib/python3.11/site-packages/pylink/jlink.py", line 142, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pi/devops_agent/_work/1/s/env/lib/python3.11/site-packages/pylink/jlink.py", line 1138, in connect
    raise errors.JLinkException(result)
pylink.errors.JLinkException: Unspecified error.

Using JLinkExe in the same SDK will work without any issue. Just using Pylink crashes.

There seems not to be a reproducible way of recovering from this situation. I need to power cycle the whole system, reboot the Raspberry Pi separately and connect and reset the target a number of times and it will (after a lot of trials) go back to an operational state.

Is this a known bug? Does Pylink or the JLink library store any persistent state in the flash which can cause this?

Thank you very much for your time. Alberto

hkpeprah commented 3 months ago

Can you run with verbose logging enabled, and provide that output?

import logging

logging.basicConfig(level=logging.DEBUG)
alpevi commented 3 months ago

Can you run with verbose logging enabled, and provide that output?

import logging

logging.basicConfig(level=logging.DEBUG)

Here the verbose output:

Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> import pylink
>>> from pylink import JLink
>>> perico = JLink()
>>> perico.open()
DEBUG:pylink.jlink:T82745700 013:030.637
DEBUG:pylink.jlink:Looking for J-Link GUI Server exe at: /tmp/JLinkGUIServerExe

DEBUG:pylink.jlink:T82745700 013:031.151
DEBUG:pylink.jlink:Looking for J-Link GUI Server exe at: /opt/SEGGER/JLink/JLinkGUIServerExe

DEBUG:pylink.jlink:T82745700 013:339.133
DEBUG:pylink.jlink:Failed to connect to J-Link GUI Server.

DEBUG:pylink.jlink:T82745700 013:340.833
DEBUG:pylink.jlink:Firmware: J-Link OB-nRF5340-NordicSemi compiled Oct 30 2023 12:13:06
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:341.675
DEBUG:pylink.jlink:Firmware: J-Link OB-nRF5340-NordicSemi compiled Oct 30 2023 12:13:06
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:369.327
DEBUG:pylink.jlink:Hardware: V1.00
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:369.538
DEBUG:pylink.jlink:S/N: 1050278255
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:369.694
DEBUG:pylink.jlink:OEM: SEGGER
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:369.853
DEBUG:pylink.jlink:Feature(s): RDI, FlashBP, FlashDL, JFlash, GDB
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:370.429
DEBUG:pylink.jlink:Bootloader: 2021 May 18
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:370.954
DEBUG:pylink.jlink:USB speed mode: Full speed (12 MBit/s)
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:371.533
DEBUG:pylink.jlink:TELNET listener socket opened on port 19021
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:371.898
DEBUG:pylink.jlink:WEBSRV WEBSRV_Init(): Starting webserver thread(s)
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:372.321
DEBUG:pylink.jlink:WEBSRV Webserver running on local port 19080
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:372.573
DEBUG:pylink.jlink:- 522.954ms returns "O.K."

DEBUG:pylink.jlink:T82745700 013:372.790
DEBUG:pylink.jlink:JLINK_SetHookUnsecureDialog

DEBUG:pylink.jlink:T82745700 013:372.928
DEBUG:pylink.jlink:JLINK_SetHookUnsecureDialog(...)
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 013:373.083
DEBUG:pylink.jlink:- 0.293ms returns 0

>>> perico.set_tif(pylink.enums.JLinkInterfaces.SWD)
DEBUG:pylink.jlink:T82745700 025:223.371
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 025:223.923
DEBUG:pylink.jlink:- 0.550ms returns 0x01

DEBUG:pylink.jlink:T82745700 025:224.259
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 025:224.666
DEBUG:pylink.jlink:- 0.405ms returns 0x01

DEBUG:pylink.jlink:T82745700 025:225.108
DEBUG:pylink.jlink:JLINK_EMU_IsConnected()

DEBUG:pylink.jlink:T82745700 025:225.457
DEBUG:pylink.jlink:- 0.349ms returns TRUE

DEBUG:pylink.jlink:T82745700 025:225.791
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 025:226.101
DEBUG:pylink.jlink:- 0.309ms returns 0x01

DEBUG:pylink.jlink:T82745700 025:226.421
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 025:226.742
DEBUG:pylink.jlink:- 0.320ms returns 0x01

DEBUG:pylink.jlink:T82745700 025:227.054
DEBUG:pylink.jlink:JLINK_EMU_IsConnected()

DEBUG:pylink.jlink:T82745700 025:227.361
DEBUG:pylink.jlink:- 0.306ms returns TRUE

DEBUG:pylink.jlink:T82745700 025:227.736
DEBUG:pylink.jlink:JLINK_TIF_GetAvailable(...)

DEBUG:pylink.jlink:T82745700 025:228.228
DEBUG:pylink.jlink:- 0.491ms

DEBUG:pylink.jlink:T82745700 025:228.723
DEBUG:pylink.jlink:JLINK_TIF_Select(JLINKARM_TIF_SWD)

DEBUG:pylink.jlink:T82745700 025:229.542
DEBUG:pylink.jlink:- 0.819ms returns 0x00

True
>>> perico.connect(chip_name='NRF52840_XXAA')
DEBUG:pylink.jlink:T82745700 031:906.098
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 031:906.644
DEBUG:pylink.jlink:- 0.546ms returns 0x01

DEBUG:pylink.jlink:T82745700 031:906.991
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 031:907.320
DEBUG:pylink.jlink:- 0.327ms returns 0x01

DEBUG:pylink.jlink:T82745700 031:907.645
DEBUG:pylink.jlink:JLINK_EMU_IsConnected()

DEBUG:pylink.jlink:T82745700 031:907.966
DEBUG:pylink.jlink:- 0.319ms returns TRUE

DEBUG:pylink.jlink:T82745700 031:908.492
DEBUG:pylink.jlink:JLINK_DEVICE_GetIndex(sDeviceName = NRF52840_XXAA)

DEBUG:pylink.jlink:T82745700 031:990.217
DEBUG:pylink.jlink:- 81.721ms returns 3505

DEBUG:pylink.jlink:T82745700 031:991.411
DEBUG:pylink.jlink:JLINK_DEVICE_GetInfo(DeviceIndex = -1)

DEBUG:pylink.jlink:T82745700 031:991.928
DEBUG:pylink.jlink:- 0.519ms returns 10341

DEBUG:pylink.jlink:T82745700 031:992.504
DEBUG:pylink.jlink:JLINK_DEVICE_GetInfo(DeviceIndex = 3505)

DEBUG:pylink.jlink:T82745700 031:992.972
DEBUG:pylink.jlink:- 0.468ms returns 0

DEBUG:pylink.jlink:T82745700 031:993.729
DEBUG:pylink.jlink:JLINK_ExecCommand("Device = NRF52840_XXAA", ...).

INFO:pylink.jlink:Device "NRF52840_XXAA" selected.
DEBUG:pylink.jlink:T82745700 032:001.357
DEBUG:pylink.jlink:Device "NRF52840_XXAA" selected.
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:009.319
DEBUG:pylink.jlink:- 15.085ms returns 0x00

DEBUG:pylink.jlink:T82745700 032:009.695
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 032:009.855
DEBUG:pylink.jlink:- 0.160ms returns 0x01

DEBUG:pylink.jlink:T82745700 032:010.009
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 032:010.154
DEBUG:pylink.jlink:- 0.145ms returns 0x01

DEBUG:pylink.jlink:T82745700 032:010.300
DEBUG:pylink.jlink:JLINK_EMU_IsConnected()

DEBUG:pylink.jlink:T82745700 032:010.446
DEBUG:pylink.jlink:- 0.145ms returns TRUE

DEBUG:pylink.jlink:T82745700 032:010.651
DEBUG:pylink.jlink:JLINK_SetSpeed(0)

INFO:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:T82745700 032:011.050
DEBUG:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:011.278
DEBUG:pylink.jlink: J-Link Script File: Executing InitTarget()

INFO:pylink.jlink:InitTarget() end - Took 5.68ms
DEBUG:pylink.jlink:T82745700 032:017.078
DEBUG:pylink.jlink:InitTarget() end - Took 5.68ms
DEBUG:pylink.jlink:

INFO:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:T82745700 032:072.909
DEBUG:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:073.136
DEBUG:pylink.jlink: J-Link Script File: Executing InitTarget()

INFO:pylink.jlink:InitTarget() end - Took 5.70ms
DEBUG:pylink.jlink:T82745700 032:078.933
DEBUG:pylink.jlink:InitTarget() end - Took 5.70ms
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:079.153
DEBUG:pylink.jlink:- 68.502ms

DEBUG:pylink.jlink:T82745700 032:079.324
DEBUG:pylink.jlink:JLINK_IsOpen()

DEBUG:pylink.jlink:T82745700 032:079.479
DEBUG:pylink.jlink:- 0.155ms returns 0x01

DEBUG:pylink.jlink:T82745700 032:079.634
DEBUG:pylink.jlink:JLINK_EMU_IsConnected()

DEBUG:pylink.jlink:T82745700 032:079.782
DEBUG:pylink.jlink:- 0.147ms returns TRUE

DEBUG:pylink.jlink:T82745700 032:079.995
DEBUG:pylink.jlink:JLINK_IsConnected()

DEBUG:pylink.jlink:T82745700 032:080.160
DEBUG:pylink.jlink:- 0.165ms returns FALSE

DEBUG:pylink.jlink:T82745700 032:080.326
DEBUG:pylink.jlink:JLINK_Connect()

INFO:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:T82745700 032:080.758
DEBUG:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:080.972
DEBUG:pylink.jlink: J-Link Script File: Executing InitTarget()

INFO:pylink.jlink:InitTarget() end - Took 5.72ms
DEBUG:pylink.jlink:T82745700 032:086.778
DEBUG:pylink.jlink:InitTarget() end - Took 5.72ms
DEBUG:pylink.jlink:

INFO:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:T82745700 032:142.282
DEBUG:pylink.jlink:InitTarget() start
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:142.496
DEBUG:pylink.jlink: J-Link Script File: Executing InitTarget()

INFO:pylink.jlink:InitTarget() end - Took 5.67ms
DEBUG:pylink.jlink:T82745700 032:148.260
DEBUG:pylink.jlink:InitTarget() end - Took 5.67ms
DEBUG:pylink.jlink:

DEBUG:pylink.jlink:T82745700 032:148.496
DEBUG:pylink.jlink:- 68.169ms returns 0xFFFFFFFF

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/devops_agent/_work/1/s/env/lib/python3.11/site-packages/pylink/jlink.py", line 142, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pi/devops_agent/_work/1/s/env/lib/python3.11/site-packages/pylink/jlink.py", line 1138, in connect
    raise errors.JLinkException(result)
pylink.errors.JLinkException: Unspecified error.
hkpeprah commented 3 months ago

Is it possible that your target is debug locked, and you need to perform a debug unlock sequence? I believe someone else ran into this same issue, though I'm not sure if they resolved it: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fdif.html

PyLink does not do the unlocking automatically, it has to be manually done by you using the CoreSight interface.

alpevi commented 3 months ago

I have checked that but it does not seem the be the issue. Following the link provided, I have manually unlocked the device (which was IMO already not locked) without any change in the Pylink behavior:

J-Link>mem32 0x10001208 1
10001208 = FFFFFFFF
J-Link>w4 0x10001208 0x0000005A
Writing 0000005A -> 10001208
J-Link>r
Reset delay: 0 ms
Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (4096 bytes)
J-Link: Flash download: Total: 0.262s (Prepare: 0.120s, Compare: 0.001s, Erase: 0.000s, Program & Verify: 0.072s, Restore: 0.068s)
J-Link: Flash download: Program & Verify speed: 55 KB/s
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
J-Link>mem32 0x10001208 1
10001208 = 0000005A

This was using JLinkExe directly

hkpeprah commented 2 months ago

The Exe will automatically perform a chip-specific debug unlocking procedure when you run it. PyLink does not automatically do this. While I don't have experience with it personally, the NRF52840 product page mentions that it has a Debug Control, and Access Port Protection. Because of this, it might be necessary for you to talk to the CoreSight interface prior to connecting in order to "unlock" the debug port, which may be automatically locked when the debugger de-attaches. Unfortunately, these sequences must be implemented per-chip family. There's an example of these sequences in the OpenOCD repository here: https://github.com/openocd-org/openocd/blob/master/tcl/target/nrf52.cfg#L56

The issue also might just be the reset method being used.