This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRFutil DFU over BLE works the first time and then fails with error code 13

Hi Everyone, 

I'm using nrfutil in an arm cortex a8 running Debian 9 with kernel 4.14.49. The processor is connected to a NRF52 dongle through USB. I'm trying to flash (using DFU) a new application to a remote NRF52 chip through BLE. I can successfully send the application firmware one time, but if I try to repeat the operation I get an error. To get rid of the error I need to disconnect and re-connect the USB (NRF52 Dongle), then I can send one new application successfully, and after that the error repeats itself.

The software versions:
nrfutils was installed from pip and its version 3.5.1
pc-ble-driver-py was compiled from source and its version 0.11.3
The firmware running in the NRF52 usb dongle is the connectivity firmware example from the SDK 15.0 for softdevice 132, (named ser_s132v3_usb_hci).

The error output that I get (for the second attempt to send th DFU over BLE) is:

user@system:~$ nrfutil -v -v dfu ble -ic NRF52 -pkg ~/nrfutils/bt_data_logger_mr_pickle.zip -p /dev/ttyACM0 -n "Pickle 15791"
2018-09-20 11:43:57,826 Shared library: /usr/local/lib/python2.7/dist-packages/pc_ble_driver_py-0.11.3-py2.7.egg/pc_ble_driver_py/lib/linux/x86_32/libpc_ble_driver_shared_sd_api_v3.so
2018-09-20 11:43:57,830 Swig module name: pc_ble_driver_sd_api_v3
2018-09-20 11:43:58,279 Using connectivity board at serial port: /dev/ttyACM0
2018-09-20 11:43:58,319 Sending Application image.
Traceback (most recent call last):
File "/usr/local/bin/nrfutil", line 11, in <module>
sys.exit(cli())
File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/nordicsemi/__main__.py", line 840, in ble
dfu.dfu_send_images()
File "/usr/local/lib/python2.7/dist-packages/nordicsemi/dfu/dfu.py", line 141, in dfu_send_images
self._dfu_send_image(self.manifest.application)
File "/usr/local/lib/python2.7/dist-packages/nordicsemi/dfu/dfu.py", line 97, in _dfu_send_image
self.dfu_transport.open()
File "/usr/local/lib/python2.7/dist-packages/nordicsemi/dfu/dfu_transport_ble.py", line 450, in open
self.dfu_adapter.open()
File "/usr/local/lib/python2.7/dist-packages/nordicsemi/dfu/dfu_transport_ble.py", line 106, in open
self.adapter.driver.open()
File "/usr/local/lib/python2.7/dist-packages/pc_ble_driver_py-0.11.3-py2.7.egg/pc_ble_driver_py/ble_driver.py", line 127, in wrapper
raise NordicSemiException('Failed to {}. Error code: {}'.format(wrapped.__name__, err_code))
pc_ble_driver_py.exceptions.NordicSemiException: Failed to open. Error code: 13

Any idea of where this error might come from? I tried to reset the NRF52 dongle, but it does not solve the problem. Any help would be very appreciated. 

Parents Reply
  • Thanks for confirming, and for the additional details, it's definitely useful information. The developers suspect it might be timing related, either in the connectivity FW or in the host implementation, but it is difficult to track down unfortunately. There was a similar issue reported here where the problem actually got resolved by updating the kernel itself, but I doubt it is a kernel issue. 

    I've confirmed this exact behavior on the beaglebone black wireless board which is not the outcome I had hoped for. I hoped it would work if I tried to build everything from scratch on a fresh install. 

Children
  • Thanks for letting me know. I saw that similar issue and was hoping that we wouldn't need to start playing with our kernel. Hopefully the developers will be able to identify where the issue is coming from.

    Please keep us posted with your findings.

  • I found this interesting comment in uart_boost.cpp (on master branch):

    serialPort->open(portName);

    // Wait a bit before making the device available since there are problems 
    // if data is sent right after open.
    //
    // Not sure if this is an OS issue or if it is an issue with the device USB stack.
    // The 200ms wait time is based on testing with PCA10028, PCA10031 and PCA10040.
    // All of these devices use the Segger OB which at the time of testing has firmware version
    // "J-Link OB-SAM3U128-V2-NordicSemi compiled Jan 12 2018 16:05:20"
    //std::this_thread::sleep_for(std::chrono::milliseconds(200));

    So I added a delay after port open like the comment suggested and it seems to have fixed the issue. I performed a loop test (100x) and got zero failures. Can you try the same on your side to confirm?  

    My pc-ble-driver-py build:

    outdir.zip

    Note: I wasn't sure how to use the sleep_for() function, so just used a for loop instead. 

    Update: std::this_thread::sleep_for(std::chrono::milliseconds(200)); depends on chrono.h and thread.h. Should work if you add those includes to uart_boost.cpp. 

  • Hello Vidar,

    This is great news! I added the wait function to uart_boost.cpp right after the serialPort->open(portName); so my try statement now looks like this:

     try
        {
            serialPort.open(portName);
            std::this_thread::sleep_for(std::chrono::milliseconds(200));
        }
    

    Recompiled the driver and now it works without any problems.

    Thanks a lot for your great and quick support!

  • Thanks for confirming the fix! It was the 2nd workaround you found that pointed me in the right direction.

    "Running a small python script which just opens and closes the serial port between DFUs - works if I run the script every time."

  • I'm glad I was able to help Slight smile

    I didn't even think about looking into the files on the master branch. It's a great thing that the developers added that comment. I hope this gets implemented in the next version update.

Related