Using nrfutil to program an off-the-shelf XIAO nRF52840 module

System Details:

  • Chip: nRF52840, XIAO Module
  • nRF5 SDK: Version 16.0.0
  • mdk version: 8.46.0
  • nrfjprog version: 10.15.4 external
  • nrfutil version: 6.1.3
  • JLinkARM.dll version: 7.64d

Hello,

I have tested an nRF SDK example application (usbd_generic_hids) on my nRF52840 DK board, and I now would like to try and flash this application onto my off-the-shelf XIAO nRF52840 modules. I have used nrfutil in the past in order to perform DFU, but it has always been for OTA DFU via BLE. I want to know how I can program just the application itself. I believe this usbd_generic_hids example does not require a SoftDevice to be present, and I am not sure if it needs a bootloader (I dont think so).

I havent programmed an off-the-shelf module like this before, so I have a few questions:

  1. I know that the XIAO module comes with a USB bootloader built-in, and I was recommended to leave that bootloader intact for easier programming. However, as I said before, I am familiar with OTA DFU and secure dfu bootloaders on the nRF52840, so I should be able to program this device wirelessly and not have to worry about overwriting the default XIAO bootloader with a nRF-based bootloader. I would personally prefer to use our normal dfu secure bootloader, with softdevice, because this is more consistent with the other versions of this device that I have been developing. Is this possible? Is there anything I should be aware of in this process?
  2. I have tried using nrfutil to generate a package of the application code by itself. It compiles and creates the .zip package just fine, but it fails to actually perform the DFU (error message included below). Is it even possible to do what I am trying? I feel like I need the dfu bootloader on-board in order to perform this usb-based dfu process.
    + nrfutil pkg generate --hw-version 52 --sd-req 0xCA --application-version 1 --application ../nrf-sdk/examples/peripheral/usbd_hid_generic/pca10056/blank/armgcc/_build/nrf52840_xxaa.hex usbd_hid.zip                         
                                                                                                                                                                                                                                   
    |===============================================================|                                                                                                                                                              
    |##      ##    ###    ########  ##    ## #### ##    ##  ######  |                                                                                                                                                              
    |##  ##  ##   ## ##   ##     ## ###   ##  ##  ###   ## ##    ## |                                                                                                                                                              
    |##  ##  ##  ##   ##  ##     ## ####  ##  ##  ####  ## ##       |                                                                                                                                                              
    |##  ##  ## ##     ## ########  ## ## ##  ##  ## ## ## ##   ####|                                                                                                                                                              
    |##  ##  ## ######### ##   ##   ##  ####  ##  ##  #### ##    ## |                                                                                                                                                              
    |##  ##  ## ##     ## ##    ##  ##   ###  ##  ##   ### ##    ## |                                                                                                                                                              
    | ###  ###  ##     ## ##     ## ##    ## #### ##    ##  ######  |                                                                                                                                                              
    |===============================================================|                                                                                                                                                              
    |You are not providing a signature key, which means the DFU     |                                                                                                                                                              
    |files will not be signed, and are vulnerable to tampering.     |                                               
    |This is only compatible with a signature-less bootloader and is|                                               
    |not suitable for production environments.                      |                                               
    |===============================================================|                                               
                                                                                                                    
    Zip created at usbd_hid.zip                                                                                     
    + nrfutil dfu usb-serial -pkg usbd_hid.zip -p /dev/cu.usbmodem14301 -b 115200                                   
      [------------------------------------]    0%                                                                  
    Traceback (most recent call last):                                                                              
      File "/usr/local/bin/nrfutil", line 8, in <module>                                                            
        sys.exit(cli())                                                                                             
      File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1128, in __call__                           
        return self.main(*args, **kwargs)                                                                           
      File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1053, in main                               
        rv = self.invoke(ctx)                                                                                       
      File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1659, in invoke                             
        return _process_result(sub_ctx.command.invoke(sub_ctx))                                                     
      File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1659, in invoke                             
        return _process_result(sub_ctx.command.invoke(sub_ctx))                                                     
      File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1395, in invoke                             
        return ctx.invoke(self.callback, **ctx.params)                                                              
      File "/usr/local/lib/python3.9/site-packages/click/core.py", line 754, in invoke                              
        return __callback(*args, **kwargs)                                                                          
      File "/usr/local/lib/python3.9/site-packages/nordicsemi/__main__.py", line 1022, in usb_serial
        do_serial(package, port, connect_delay, flow_control, packet_receipt_notification, baud_rate, serial_number, False,
      File "/usr/local/lib/python3.9/site-packages/nordicsemi/__main__.py", line 978, in do_serial                                                                                                                                 
        dfu.dfu_send_images()                               
      File "/usr/local/lib/python3.9/site-packages/nordicsemi/dfu/dfu.py", line 127, in dfu_send_images
        self._dfu_send_image(self.manifest.application)     
      File "/usr/local/lib/python3.9/site-packages/nordicsemi/dfu/dfu.py", line 88, in _dfu_send_image                                                                                                                             
        self.dfu_transport.open()                           
      File "/usr/local/lib/python3.9/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 217, in open                                                                                                                      
        self.__get_mtu()                                                                                            
      File "/usr/local/lib/python3.9/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 366, in __get_mtu                                                                                                                 
        self.mtu = struct.unpack('<H', bytearray(response))[0]                       
    TypeError: cannot convert 'NoneType' object to bytearray  
  3. Any general advice on what resources will help me learn how to do this?

Thank you in advance :)

Parents
  • According to https://wiki.seeedstudio.com/XIAO_BLE/ the manufacturer advises flashing this device through the Arduino GUI.  Are you sure their default bootloader implements a serial protocol compatible with nrfutil?

    However, as I said before, I am familiar with OTA DFU and secure dfu bootloaders on the nRF52840, so I should be able to program this device wirelessly and not have to worry about overwriting the default XIAO bootloader with a nRF-based bootloader

    FWIW: I started off using nrfutil to program my nRF52840 Dongles through the Open Bootloader that it ships with.  This was sufficient for early prototyping and evaluation.  But when it came time to support OTA updates I wanted our own public key embedded into the bootloader so that it would only accept properly signed release images.  I also wanted to enforce a static partition map that won't change in future builds.  So I reflashed the dongles with a homebuilt mcuboot image through the SWD pins (just SWIO, SWCLK, GND).

  • Thanks for the quick response  

    Are you sure their default bootloader implements a serial protocol compatible with nrfutil?

    Good question. No I am not sure.

    I was recommended this specific module and the recommender also mentioned that I could use nrfutil to program it. I have taken their word on good faith, but I am not 100% sure that it is accurate. This is sort of why I came to this forum after running into issues.

    I am familiar with the Arduino IDE, but have never used it to flash a separate application. I see in the docs that you linked that it is possible to get simple Arduino example code running on the board, but I wonder: Is it possible to flash my compiled nRF SDK application .hex/.bin file directly to the XIAO board via the Arduino IDE? Are there any resources out there where I could read more about this kind of thing? Is the first comment on this thread relevant?
    or will I have to create an Arduino IDE-created version of my nRF52840 application from scratch? I hope there is an easier option than this...

    So I reflashed the dongles with a homebuilt mcuboot image through the SWD pins (just SWIO, SWCLK, GND).

    I was also thinking this could be a realistic option, but wanted to see if there might be a software solution. Good to know its not too unreasonable to take this route if all else fails.

    Thanks again for the help,

    Corten

  • To be clear, I only temporarily grounded the RST pin with a jumper cable (unsoldered) - I didnt leave it grounded.

    If the device node is still present, and you're getting "Device not configured" (ENXIO) when you try to talk to it, that suggests to me that you might have successfully activated the bootloader but your host isn't able to talk to it due to USB interop bugs.  e.g. maybe the bootloader has a different version of the USB stack from the main app

    If you have a Linux box or Raspberry Pi lying around, maybe try flashing with one of those?

    Otherwise, it is looking more and more likely that I will just solder up some connections to the SWD pads on the module and program it using a JLINK like I have done with other boards.

    IMO the support for these USB bootloaders is pretty half-baked, even on the official Nordic dongles.  I wonder if they'd accept a pull request to clean it up.

  • Hello  and ,

    I am having trouble replying to the most recent comment left by Mytzjay, but I was able to learn a bit more about the device. I found some information on board my XIAO module that mentions the bootloader, as well as some other high level details. Take a look:

    UF2 Bootloader 0.6.2-12-g459adc9-dirty lib/nrfx (v2.0.0) lib/tinyusb (0.10.1-293-gaf8e5a90) lib/uf2 (remotes/origin/configupdate-9-gadbb8c7)
    Model: Seeed XIAO nRF52840
    Board-ID: Seeed_XIAO_nRF52840_Sense
    Date: Nov 30 2021
    SoftDevice: S140 7.3.0
    

    Right off the bat, I notice that my SoftDevice s140 is version 7.0.1, while this XIAO module has s140 version 7.0.3. Could this difference in version be causing these issues?

    Aside from that, I am not entirely sure how to make sense of the bootloader information. Do these bootloader details give us a better understanding of what is going on? Any help is greatly appreciated.

    EDIT: I connected a JLINK to the XIAO module by soldering wires to the SWDIO, SWDCLK, RST, GND and 3.3V pins. This method is working for me and I am getting all of my code onto the device as expected. Thank you for working with me to try and help debug using the USB as a means of DFU. If this bootloader information that I shared sheds light on my previous failures, I would still love to learn what is going on...plus I have to program a handful of these boards and it would be easier over USB, though not needed.

  • Hello,

    I'm glad to hear that you were able to program the module through the debug interface.

    cor10 said:
    Why is this the case? For example, when I plug in the nRF52840 DK, it also appears as a flash storage icon. So why does this fact help us distinguish that it is not a Nordic bootloader?

    The main USB on the DK is connected to the standalone J-link interface chip and not to the nRF52840's USB (the nRF usb is the one on the side). The J-link will enumerate as a composite device with 1-2 VCOM ports and a mass storage device.

    cor10 said:
    I am having trouble replying to the most recent comment left by Mytzjay, but I was able to learn a bit more about the device. I found some information on board my XIAO module that mentions the bootloader, as well as some other high level details. Take a look:

    UF2 is a different bootloader which you can read more about here: https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/uf2-bootloader-details

  • It looks like I hosed the softdevice on my XIAO using one/some of the NRF5 SDK examples. The UF2 mass storage bootloader interface takes the executables, but they simply don't work.(It could be that I zapped the bootloader in the process as well). Any ideas how to use the UF2 bootloader to replace the softdevice and/or the UF2 bootloader itself. I'd like to avoid messing with j-link for the moment.

  • I managed to fix it. The UF2 bootloader is apparently protected so it likely survived my testing completely unscathed. However, the bootloader can be updated and likely replaced through the mass storage and likely the BOSSA emulated serial interface using some "secret" wrapper code: learn.adafruit.com/.../uf2-bootloader-details

    To restore the softdevice, I simply ran the uf2conv.py -c -f 0xADA52840 -o s140_nrf52_7.3.0_softdevice.uf2 s140_nrf52_7.3.0_softdevice.hex on the softdevice file and uploaded it via the UF2 mass storage interface. In the process I learned that the softdevice is loaded at 0x0 and the executable is expected at 0x27000.

    Running code that does not require the softdevice can be accomplished by compiling and linking it with a 0x27000 start address (yes, you loose some code storage, but gain convenience and flexibility). You need to massage the .emProject file and perhaps the local .ld file (or delete the local .ld file so the default is used). It worked for me. I believe the bootloader and not the softdevice expects the executable to be at 0x27000.

    Some UF2 bootloader sources state that you need 7.x softdevice and that 6.x is incompatible, but I suspect it may be that 6.x executables are compiled to start at 0x26000, which can likely be changed to 0x27000 just like the 0x0 start executables. However, I haven't tested with 6.x.

Reply
  • I managed to fix it. The UF2 bootloader is apparently protected so it likely survived my testing completely unscathed. However, the bootloader can be updated and likely replaced through the mass storage and likely the BOSSA emulated serial interface using some "secret" wrapper code: learn.adafruit.com/.../uf2-bootloader-details

    To restore the softdevice, I simply ran the uf2conv.py -c -f 0xADA52840 -o s140_nrf52_7.3.0_softdevice.uf2 s140_nrf52_7.3.0_softdevice.hex on the softdevice file and uploaded it via the UF2 mass storage interface. In the process I learned that the softdevice is loaded at 0x0 and the executable is expected at 0x27000.

    Running code that does not require the softdevice can be accomplished by compiling and linking it with a 0x27000 start address (yes, you loose some code storage, but gain convenience and flexibility). You need to massage the .emProject file and perhaps the local .ld file (or delete the local .ld file so the default is used). It worked for me. I believe the bootloader and not the softdevice expects the executable to be at 0x27000.

    Some UF2 bootloader sources state that you need 7.x softdevice and that 6.x is incompatible, but I suspect it may be that 6.x executables are compiled to start at 0x26000, which can likely be changed to 0x27000 just like the 0x0 start executables. However, I haven't tested with 6.x.

Children
No Data
Related