I'm migrating a production jig driver application from using multiple calls to an nrfjprog binary to the pynrfjprog library instead. It's gone almost perfectly, but I have a problem I can't figure out: after I've done all the steps--erased, reflashed, and reset the target device--I can't clean up the connection by closing the connection to the target device, or to the J-Link (emu), or to the DLL API in Python. It just hangs forever if I try. The only thing that works instead is killing the process and restarting it.
I'm running a virtualenv (managed by pipenv) of Python 3.11.4 on a Macbook Pro (macOS Sonoma 14.1), with pynrfjprog v10.23.2 (the latest as of this post). I'm flashing a u-blox BMD-340 module built around an nRF52840 chip. I have no issues whatsoever flashing it with other means.
I originally thought the problem was related to some threading that I had in my code, but I pared it down to something as simple as possible, and it still happens. Here's the code that I'm testing with:
When I run this, the output stops before the disconnection from the target device completes. This shows a limited stack trace for where it's stuck after I press Ctrl+C:
If I comment out the call to nrf_api.disconnect_from_device()
, then it hangs inside the disconnect_from_emu()
call instead. If I comment that out, then it hangs inside the nrf_api
object's close()
call instead. If I comment all of the clean-up out entirely and let the app attempt to deal with it, like a neanderthal, then the final build-in exit()
call never returns, and a Ctrl+C reveals it's still stuck inside self._lib.NRFJPROG_close_dll_inst(ctypes.byref(self._handle))
.
How can I fix this? Needing to kill and restart the jig driver script after every device goes through it kinda defeats the purpose.