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

pc_ble_driver_py.exceptions.NordicSemiException: Response Code OperationNotPermitted

I've been developing firmware for my PCA10059.

I load the package with nrfutil dfu usb-serial --package=_build/t.zip --serial-number=`cat /tmp/serials.txt` --connect-delay=0

This usually works OK.  But one time I realized halfway through the upload that I was loading the wrong firmware, and I terminated with control-C (SIGINT). Since that event, I can no longer upload code to the dongle.

Instead, I get this error:

nrfutil dfu usb-serial --package=_build/t.zip --serial-number=`cat /tmp/serials.txt` --connect-delay=0

Traceback (most recent call last):
  File "/home/markrages/.local/bin/nrfutil", line 11, in <module>
    sys.exit(cli())
  File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/__main__.py", line 1001, in usb_serial
    timeout)
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/__main__.py", line 956, in do_serial
    dfu.dfu_send_images()
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu.py", line 121, in dfu_send_images
    self._dfu_send_image(self.manifest.softdevice)
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu.py", line 102, in _dfu_send_image
    self.dfu_transport.send_firmware(data)
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 296, in send_firmware
    try_to_recover()
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 292, in try_to_recover
    self.__execute()
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 421, in __execute
    self.__get_response(DfuTransportSerial.OP_CODE['Execute'])
  File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 505, in __get_response
    get_dict_key(DfuTransport.RES_CODE, resp[2])))
pc_ble_driver_py.exceptions.NordicSemiException: Response Code OperationNotPermitted
Makefile:384: recipe for target 'usbdfu' failed
make: *** [usbdfu] Error 1

So what does OperationNotPermitted mean?  Is it possible to recover this without JTAG?  Or is it bricked?

Regards,
Mark

nrfutil version 5.2.0 on Ubuntu 18.04.

  • Hi Mark, 

    Which SDK version are you using? I took a look at the Open Bootloader source code in SDK v15.3.0 and it will return NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED at the following locations in the code

    • nRF5_SDK_15.3.0_59ac345/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c, line 406:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED; 
      Cannot create data object without valid init command
    • nRF5_SDK_15.3.0_59ac345/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c, line 442:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
      Creating the object would overflow firmware size.
    • nRF5_SDK_15.3.0_59ac345/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c, line 474:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
      Can't accept data because DFU isn't initialized by init command
    • nRF5_SDK_15.3.0_59ac345/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c, line 610:p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
      The size of the written object was not as expected
    • nRF5_SDK_15.3.0_59ac345/components/libraries/bootloader/dfu/nrf_dfu_validation.c, line 591:ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
      Execute with faulty offset. The object wasn't the right (requested) size. 

    Could you debug the bootloader or use the debug version( i.e. \examples\dfu\open_bootloader\pca10059_usb_debug) and see where the response code is originating from?

    Best regards

    Bjørn

  • I don't have JTAG/SWD access to the dongle right now.

    I was able to unbrick the dongle with the following sequence:

    1. Edit dfu_transport_serial.py like so:
      --- dfu_transport_serial.py.orig	2020-02-19 10:32:26.253374608 -0600
      +++ dfu_transport_serial.py	2020-02-19 10:33:01.336063321 -0600
      @@ -293,7 +293,7 @@
                   self._send_event(event_type=DfuEvent.PROGRESS_EVENT, progress=response['offset'])
       
               response = self.__select_data()
      -        try_to_recover()
      +        # try_to_recover()
               for i in range(response['offset'], len(firmware), response['max_size']):
                   data = firmware[i:i+response['max_size']]
                   try:
      
    2. Try to upload the firmware again, withe the following response:
      nrfutil dfu usb-serial --package=_build/t.zip --serial-number=`cat /tmp/serials.txt` --connect-delay=0
        [###########-------------------------]   32%  00:00:11
      Traceback (most recent call last):
        File "/home/markrages/.local/bin/nrfutil", line 11, in <module>
          sys.exit(cli())
        File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 764, in __call__
          return self.main(*args, **kwargs)
        File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 717, in main
          rv = self.invoke(ctx)
        File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 1137, in invoke
          return _process_result(sub_ctx.command.invoke(sub_ctx))
        File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 1137, in invoke
          return _process_result(sub_ctx.command.invoke(sub_ctx))
        File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 956, in invoke
          return ctx.invoke(self.callback, **ctx.params)
        File "/home/markrages/.local/lib/python2.7/site-packages/click/core.py", line 555, in invoke
          return callback(*args, **kwargs)
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/__main__.py", line 1001, in usb_serial
          timeout)
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/__main__.py", line 956, in do_serial
          dfu.dfu_send_images()
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu.py", line 121, in dfu_send_images
          self._dfu_send_image(self.manifest.softdevice)
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu.py", line 102, in _dfu_send_image
          self.dfu_transport.send_firmware(data)
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 302, in send_firmware
          self.__execute()
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 421, in __execute
          self.__get_response(DfuTransportSerial.OP_CODE['Execute'])
        File "/home/markrages/.local/lib/python2.7/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 502, in __get_response
          raise NordicSemiException('Extended Error 0x{:02X}: {}'.format(resp[3], data))
      pc_ble_driver_py.exceptions.NordicSemiException: Extended Error 0x0C: The hash of the received firmware image does not match the hash in the init packet.
      Makefile:384: recipe for target 'usbdfu' failed
      make: *** [usbdfu] Error 1
    3. Try again, and it works this time.
  • Hi Mark, 

    the 0x0C error code is NRF_DFU_EXT_ERROR_VERIFICATION_FAILED, which is returned by the bootloader when the postvalidation step, where, as stated in the error message, the hast of the received firmware is compared with the hash in the init packet. 

    Are you sending the same image that was sent when you aborted or is this a firmware package? IF its the latter then that explains the error message, i.e. when you start the DFU process the bootloader will provide the last offset in the transfer that was aborted, but since you have commented out try_to_recover() from send_firmware(), then it seems that nrfutil will still use this offset when transfering the new image. When the "entire" image has been transferred then the post validation step will be performed and the hash of the firmware will be different than the hash in the initial init packet. 

    However, I would have expected that nrfutil and the bootloader to recover from an aborted transmission as it keeps track of the offset and number of data objects sent etc. Will raise this issue internally to see if there are any improvements to be made. 

    Best regards

    Bjørn

  • Hi Mark,

    We had the same issue on Linux. However the device can be recovered by sending another different image (zip), which makes this issue a recoverable situation. 

    Traceback (most recent call last):
      File "/usr/local/bin/nrfutil", line 10, in <module>
        sys.exit(cli())
      File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 764, in __call__
        return self.main(*args, **kwargs)
      File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 717, in main
        rv = self.invoke(ctx)
      File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 956, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/usr/local/lib/python3.7/dist-packages/click/core.py", line 555, in invoke
        return callback(*args, **kwargs)
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/__main__.py", line 1035, in serial
        timeout)
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/__main__.py", line 949, in do_serial
        dfu.dfu_send_images()
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/dfu/dfu.py", line 127, in dfu_send_images
        self._dfu_send_image(self.manifest.application)
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/dfu/dfu.py", line 100, in _dfu_send_image
        self.dfu_transport.send_firmware(data)
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/dfu/dfu_transport_serial.py", line 296, in send_firmware
        try_to_recover()
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/dfu/dfu_transport_serial.py", line 292, in try_to_recover
        self.__execute()
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/dfu/dfu_transport_serial.py", line 421, in __execute
        self.__get_response(DfuTransportSerial.OP_CODE['Execute'])
      File "/usr/local/lib/python3.7/dist-packages/nordicsemi/dfu/dfu_transport_serial.py", line 505, in __get_response
        get_dict_key(DfuTransport.RES_CODE, resp[2])))
    pc_ble_driver_py.exceptions.NordicSemiException: Response Code OperationNotPermitted


Related