Unable to get mcuboot to work on custom nRF52840 design.

I have a custom nRF52840 design, I'm actually using a ublox BMD-340-A-R module on a custom board. I have a working application with BLE peripheral, I2C sensors, USB CDC, LoRaWan and some RS485 interfaces. I am using NCS 2.5.2. The application is working as intended and I now want to add mcuboot for OTA DFU firmware updates. In the application I have console and logging disabled as I am using the UARTs for the RS485 interfaces so they are not available (practically all pins are in use).

Now, I've tried to add mcuboot by adding CONFIG_BOOTLOADER_MCUBOOT=y in prj.conf and a child_image/mcuboot.conf (shown below). If I connect to the device using nRFConnect App I can see that DFU service is available. If I press the DFU icon and load the app_distribution.zip it appears as if the file is uploaded (I get the transfer speed chart and the progress goes on to 100%) but right after the upload when the progress switches to "Validating..." the nRF52 reboots and gets stuck somewhere. If I power cycle the board the device comes back up but it is on the original firmware.

I'm not very familiar with mcuboot so I'm not sure what to check or try. Below are all of the file the I think are relevant.

prj.conf:

CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_UART_0_ASYNC=y
CONFIG_UART_1_ASYNC=y
CONFIG_UART_ASYNC_API=y


CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n

CONFIG_HEAP_MEM_POOL_SIZE=8192

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="dtu proto"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1

# Enable bonding
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y


# Config logger
CONFIG_LOG=n
CONFIG_USE_SEGGER_RTT=n
CONFIG_LOG_BACKEND_RTT=n
CONFIG_LOG_PRINTK=n


CONFIG_ASSERT=y

CONFIG_GPIO_AS_PINRESET=n

# Enable USB
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_CDC_ACM=y
CONFIG_USB_WORKQUEUE=y
CONFIG_USB_WORKQUEUE_STACK_SIZE=8192


CONFIG_LOG_DEFAULT_LEVEL=3
CONFIG_CBPRINTF_FP_SUPPORT=y


CONFIG_SHELL=n
CONFIG_LORA=y
CONFIG_SPI=y
CONFIG_ADC=y
CONFIG_LORA_SX127X=y


# Enable the LoraWAN stack
CONFIG_LORAWAN=y
#CONFIG_LORAWAN_LOG_LEVEL_DBG=y
CONFIG_HAS_SEMTECH_LORAMAC=y
CONFIG_HAS_SEMTECH_SOFT_SE=y
CONFIG_HAS_SEMTECH_RADIO_DRIVERS=y

# Configure LoraWAN Region to be used
CONFIG_LORAMAC_REGION_EU868=y

CONFIG_INIT_STACKS=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192

CONFIG_NO_OPTIMIZATIONS=n

CONFIG_UART_INTERRUPT_DRIVEN=y

CONFIG_BOOTLOADER_MCUBOOT=y

CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y
CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP=y

CONFIG_PWM=y
CONFIG_PWM_NRFX=y

CONFIG_MCUMGR=y
CONFIG_MCUMGR_TRANSPORT_BT=y

child_image/mcuboot.conf:

CONFIG_SHELL=n

CONFIG_LOG=n


CONFIG_CONSOLE=n


CONFIG_GPIO_AS_PINRESET=n


CONFIG_BOOT_SIGNATURE_TYPE_RSA=y

CONFIG_MULTITHREADING=y

pm_static.yml (copied from partition.yml)

app:
  address: 0xc200
  end_address: 0x85000
  region: flash_primary
  size: 0x78e00
mcuboot:
  address: 0x0
  end_address: 0xc000
  placement:
    before:
    - mcuboot_primary
  region: flash_primary
  size: 0xc000
mcuboot_pad:
  address: 0xc000
  end_address: 0xc200
  placement:
    align:
      start: 0x1000
    before:
    - mcuboot_primary_app
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0xc000
  end_address: 0x85000
  orig_span: &id001
  - app
  - mcuboot_pad
  region: flash_primary
  sharers: 0x1
  size: 0x79000
  span: *id001
mcuboot_primary_app:
  address: 0xc200
  end_address: 0x85000
  orig_span: &id002
  - app
  region: flash_primary
  size: 0x78e00
  span: *id002
mcuboot_secondary:
  address: 0x85000
  end_address: 0xfe000
  placement:
    after:
    - mcuboot_primary
    align:
      start: 0x1000
  region: flash_primary
  share_size:
  - mcuboot_primary
  size: 0x79000
settings_storage:
  address: 0xfe000
  end_address: 0x100000
  placement:
    align:
      start: 0x1000
    before:
    - end
  region: flash_primary
  size: 0x2000
sram_primary:
  address: 0x20000000
  end_address: 0x20040000
  region: sram_primary
  size: 0x40000

Parents
  • Few other things that I have tried since:

    - updated to NCS 2.6.0-rc1
    - sample application BLE Uart Service and added mcuboot 
    - nRF Connect App from different Android phone
    - using the nrf9160DK (it's the only DK with nrf52840 that I have handy at the moment)
    - changing the app version number in VERSION file

    All of these resulted in the same issue. The DFU process either exists immediately saying "Application has been sent successfully" when from what I can tell this is not true or it appears to upload, then reboots and hangs when Validation starts.

  • Hello,

    Please start a debug session in VS Code. After the program hangs, attempt to pause the debugger to see where the program is hanging. Additionally, you may want to experiment with the smp_srv sample using the Bluetooth overlay:

    This sample should work out-of-the-box and provide a working reference for comparison.

    George said:
    However if I choose any of the other options ("Test Only", "Confirm Only", "Upload Only")

    With 'Test Only', the application must confirm the new image. If not confirmed, MCUboot will revert to the previous application on the next reboot. 'Confirm Only' ensures the new application is confirmed automatically, preventing the bootloader from reverting to the old application. 'Upload Only' works similarly to 'Test Only', but it does not send the reset command after the transfer completes.

  • I've tried running it in the debugger but for some reason I am not getting any file upload now, it says "Done" right away and "Application has been sent successfully", but it doesn't really send it.

    Log from nRFConnect:

    nRF Connect, 2024-03-12
    dtu proto (DC:E2:CE:4E:74:40)
    V	12:43:50.401	[McuMgr] Connecting...
    D	12:43:50.412	[McuMgr] gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, LE 1M)
    D	12:43:50.477	[McuMgr] [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
    I	12:43:50.486	[McuMgr] Connected to DC:E2:CE:4E:74:40
    D	12:43:50.494	[McuMgr] wait(300)
    I	12:43:50.504	[McuMgr] MTU changed to: 498
    V	12:43:50.805	[McuMgr] Discovering services...
    D	12:43:50.816	[McuMgr] gatt.discoverServices()
    I	12:43:50.852	[McuMgr] Services discovered
    V	12:43:50.862	[McuMgr] Primary service found
    D	12:43:50.899	[McuMgr] gatt.setCharacteristicNotification(da2e7828-fbce-4e01-ae9e-261174997c48, true)
    V	12:43:50.930	[McuMgr] Enabling notifications for da2e7828-fbce-4e01-ae9e-261174997c48
    D	12:43:50.954	[McuMgr] descriptor.setValue(0x01-00)
    D	12:43:50.964	[McuMgr] gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb)
    I	12:43:51.063	[McuMgr] Data written to descr. 00002902-0000-1000-8000-00805f9b34fb
    I	12:43:51.072	[McuMgr] Notifications enabled
    V	12:43:51.078	[McuMgr] Waiting for value change...
    V	12:43:51.088	[McuMgr] Writing characteristic da2e7828-fbce-4e01-ae9e-261174997c48 (WRITE COMMAND)
    D	12:43:51.097	[McuMgr] characteristic.setValue(0x000000010000FF06A0)
    D	12:43:51.103	[McuMgr] characteristic.setWriteType(WRITE COMMAND)
    D	12:43:51.108	[McuMgr] gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
    I	12:43:51.127	[McuMgr] Data written to da2e7828-fbce-4e01-ae9e-261174997c48
    I	12:43:51.214	[McuMgr] Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 01-00-00-19-00-00-FF-06-BF-68-62-75-66-5F-73-69-7A-65-19-09-AB-69-62-75-66-5F-63-6F-75-6E-74-06-FF
    I	12:43:51.222	[McuMgr] Wait for value changed complete
    A	12:43:51.230	[McuMgr] Received Header (Version: 0, Op: 1, Flags: 0, Len: 25, Group: 0, Seq: 255, Command: 6) CBOR {"buf_size":2475,"buf_count":6}
    I	12:43:51.238	[McuMgr] SMP reassembly supported with buffer size: 2475 bytes and count: 6
    A	12:43:51.248	[McuMgr] Sending (10 bytes) Header (Version: 1, Op: 0, Flags: 0, Len: 2, Group: 0, Seq: 0, Command: 8) CBOR {}
    V	12:43:51.254	[McuMgr] Writing characteristic da2e7828-fbce-4e01-ae9e-261174997c48 (WRITE COMMAND)
    D	12:43:51.261	[McuMgr] characteristic.setValue(0x0800000200000008BFFF)
    D	12:43:51.269	[McuMgr] characteristic.setWriteType(WRITE COMMAND)
    D	12:43:51.275	[McuMgr] gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
    I	12:43:51.295	[McuMgr] Data written to da2e7828-fbce-4e01-ae9e-261174997c48
    I	12:43:51.415	[McuMgr] Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 09-00-00-15-00-00-00-08-BF-6A-62-6F-6F-74-6C-6F-61-64-65-72-67-4D-43-55-62-6F-6F-74-FF
    A	12:43:51.429	[McuMgr] Received Header (Version: 1, Op: 1, Flags: 0, Len: 21, Group: 0, Seq: 0, Command: 8) CBOR {"bootloader":"MCUboot"}
    A	12:43:51.481	[McuMgr] Sending (21 bytes) Header (Version: 1, Op: 0, Flags: 0, Len: 13, Group: 0, Seq: 1, Command: 8) CBOR {"query":"mode"}
    V	12:43:51.495	[McuMgr] Writing characteristic da2e7828-fbce-4e01-ae9e-261174997c48 (WRITE COMMAND)
    D	12:43:51.504	[McuMgr] characteristic.setValue(0x0800000D00000108BF657175657279646D6F6465FF)
    D	12:43:51.513	[McuMgr] characteristic.setWriteType(WRITE COMMAND)
    D	12:43:51.520	[McuMgr] gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
    I	12:43:51.567	[McuMgr] Data written to da2e7828-fbce-4e01-ae9e-261174997c48
    I	12:43:51.568	Connection parameters updated (interval: 11.25ms, latency: 0, timeout: 420ms)
    I	12:43:51.600	[McuMgr] Connection parameters updated (interval: 11.25ms, latency: 0, timeout: 420ms)
    I	12:43:51.608	[McuMgr] Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 09-00-00-08-00-00-01-08-BF-64-6D-6F-64-65-03-FF
    A	12:43:51.622	[McuMgr] Received Header (Version: 1, Op: 1, Flags: 0, Len: 8, Group: 0, Seq: 1, Command: 8) CBOR {"mode":3}
    A	12:43:51.661	[McuMgr] Sending (10 bytes) Header (Version: 1, Op: 0, Flags: 0, Len: 2, Group: 1, Seq: 2, Command: 0) CBOR {}
    V	12:43:51.668	[McuMgr] Writing characteristic da2e7828-fbce-4e01-ae9e-261174997c48 (WRITE COMMAND)
    D	12:43:51.673	[McuMgr] characteristic.setValue(0x0800000200010200BFFF)
    D	12:43:51.678	[McuMgr] characteristic.setWriteType(WRITE COMMAND)
    D	12:43:51.684	[McuMgr] gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
    I	12:43:51.706	[McuMgr] Data written to da2e7828-fbce-4e01-ae9e-261174997c48
    I	12:43:51.714	[McuMgr] Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 09-00-00-87-00-01-02-00-BF-66-69-6D-61-67-65-73-9F-BF-64-73-6C-6F-74-00-67-76-65-72-73-69-6F-6E-66-32-2E-31-31-2E-30-64-68-61-73-68-58-20-72-F8-08-61-0A-53-6C-0B-61-2C-86-07-8A-0B-B5-A3-68-95-56-DD-37-33-8A-54-76-AB-CE-90-4A-71-22-8A-68-62-6F-6F-74-61-62-6C-65-F5-67-70-65-6E-64-69-6E-67-F4-69-63-6F-6E-66-69-72-6D-65-64-F5-66-61-63-74-69-76-65-F5-69-70-65-72-6D-61-6E-65-6E-74-F4-FF-FF-6B-73-70-6C-69-74-53-74-61-74-75-73-00-FF
    A	12:43:51.732	[McuMgr] Received Header (Version: 1, Op: 1, Flags: 0, Len: 135, Group: 1, Seq: 2, Command: 0) CBOR {"images":[{"slot":0,"version":"2.11.0","hash":"cvgIYQpTbAthLIYHigu1o2iVVt03M4pUdqvOkEpxIoo=","bootable":true,"pending":false,"confirmed":true,"active":true,"permanent":false}],"splitStatus":0}
    V	12:43:51.763	[McuMgr] Disconnecting...
    D	12:43:51.771	[McuMgr] gatt.disconnect()
    D	12:43:51.801	[McuMgr] [Callback] Connection state changed with status: 0 and new state: 0 (DISCONNECTED)
    I	12:43:51.812	[McuMgr] Disconnected
    D	12:43:51.818	[McuMgr] gatt.close()
    I	12:43:56.816	Connection parameters updated (interval: 48.75ms, latency: 0, timeout: 420ms)
    

  • Please try the nRF Device manager app and read out the mcuboot slots from the advanced menu. It sounds like the hash for the image present on the device might be identical to the one you are trying to upload.

  • Thanks this is helpful!

    You're right that the file hash is part of the problem. How is it possible that I comment a chunk of code build the app_update.bin that has different file size and different MD5 sum from the previous and yet the hash shown in the nRF Device Manager is the same? I've just double checked this and the hash shown for both .bin files is the same.

    After some attempts (not sure what I did) I was able to get a bin file with different hash and if I do the firmware update process manually within the Device Manager app (that is, in Advanced Mode I first upload, then read, test, reset, confirm and reset ...it seems to work and I can see the slots changing hash. However if I try to do it using the "Basic" process it doesn't work.  I'm still trying things so this might not be all correct.

  • Some more info:

    - it seems there might be a bug in nRF connect app where it the file name doesn't change it keeps loading the same hash value. I was loading the .bin file directly from a Dropbox folder containing the build folder. So I would build, wait for sync and use the .bin file. If I do this, even if the bin file changes (and I can see that from size and date when selecting it) the app keeps showing the old hash and the file not uploaded. Simply renaming the .bin file loads the correct hash.

    - I tried again the manual sequence in Device Manager advanced mode and it works perfectly. If I try the same thing in Basic Mode or in nRF Connect it hangs. I need to dig further into this, but mcuboot itself appears to be working correctly.

Reply
  • Some more info:

    - it seems there might be a bug in nRF connect app where it the file name doesn't change it keeps loading the same hash value. I was loading the .bin file directly from a Dropbox folder containing the build folder. So I would build, wait for sync and use the .bin file. If I do this, even if the bin file changes (and I can see that from size and date when selecting it) the app keeps showing the old hash and the file not uploaded. Simply renaming the .bin file loads the correct hash.

    - I tried again the manual sequence in Device Manager advanced mode and it works perfectly. If I try the same thing in Basic Mode or in nRF Connect it hangs. I need to dig further into this, but mcuboot itself appears to be working correctly.

Children
  • I think I solved the issue!

    In my application main() I had a call to load settings data from NVS and I had placed this before a function that calls bt_enable() and bt_le_adv_start(). I think this was blocking the boot process during the Test mode. Moving the settings load function to after the bt initialization solved the issue.

    I had tested this before but the problem with the hash value not updating was preventing the new firmware from loading and this threw me off course. 

Related