Looking for BLE OTA Bootloader information

Hello all,

I'm looking for some information about a BLE bootloader for an NRF52840 (u-blox NINA) device. 

I do little debugging at this stage and would like to be able to update the firmware over BLE. The unit where our NRF PCB is located doesn't really allow for using j-Link for updates, although we can make a few concessions.

I've been looking for BLE Bootloader information for NRF chips, so far I understand that:

- NRF does not provide a ROM bootloader

- The bootloader has to be compiled and flashed into the microcontroller, before the application can be flashed.

- There are two types of bootloader available... is that right?

I'm working on Windows 11, the NRF SDK 2.5 and Zephyr. Can you provide me with an up to date example / tutorial and information? I'm a bit confused with what I've found so far. Basically I need a simple BLE buttonless bootloader that I can jump into from the application, and that re-starts the application after a successful update.

I may have more questions moving forward... 

Cheers,

Alberto

Parents
  • Hi Vidar,

    A little update. I was able to compile by adding these lines into my project:

    # Enable bootloader
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y

    I got the following warnings but ignored them:

    CMake Warning at C:/ncs/v2.5.0/nrf/samples/common/mcumgr_bt_ota_dfu/CMakeLists.txt:14 (message):
      MCUmgr Bluetooth OTA DFU: suboptimal configuration of Bluetooth Controller
      buffers.  Consider using optimal values defined in the
      C:/ncs/v2.5.0/nrf/samples/common/mcumgr_bt_ota_dfu/Kconfig file for
      CONFIG_BT_BUF_ACL_TX_SIZE, CONFIG_BT_BUF_ACL_RX_SIZE and
      CONFIG_BT_CTLR_DATA_LENGTH_MAX options

    The build generated two images:

    -- Zephyr version: 3.4.99 (C:/ncs/v2.5.0/zephyr), build: v3.4.99-ncs1
    [182/182] Linking C executable zephyr\zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       34880 B        48 KB     70.96%
                 RAM:       16848 B       256 KB      6.43%
            IDT_LIST:          0 GB         2 KB      0.00%
    [88/291] Building C object CMakeFiles/app.dir/src/tasks/controller.c.obj                    ^~~~~~~~~~~~
    [283/291] Linking C executable zephyr\zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:      261800 B     499200 B     52.44%
                 RAM:      153256 B       256 KB     58.46%
            IDT_LIST:          0 GB         2 KB      0.00%
    [286/291] Generating ../../zephyr/app_signed.hex
    image.py: sign the payload
    [287/291] Generating ../../zephyr/app_update.bin
    image.py: sign the payload
    [289/291] Generating ../../zephyr/app_test_update.hex
    image.py: sign the payload
    [291/291] Generating zephyr/merged.hex

    I flashed the project:

    And the micro rebooted and called the application. I was not able to see these messages:

    I'm guessing that the bootloader is there but I don't know yet. I will try to get onto jLink and start a debugging session. I was not able to set MCUBoot to print.

    My question now is... where do I find information on how to trigger MCUBoot to stay in bootloader mode? Do I need to erase the "rsp" structure perhaps, set a variable somewhere? Ah, yes, I forgot to mention, I have no physical access to the PCB in form of buttons or other.

    Anyway, it's a good start, if you can point me into the right direction I'd appreciate it.

    Cheers,

    Alberto

  • Hi Alberto,

    Albert_0 said:
    I got the following warnings but ignored them:

    It's safe to ignore. Essentially, it indicates that your DFU upload speed can be configured to be faster. You can get rid of the warnings by adding CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP=y. This will increase the speed at the expense of higher memory usage.

    Albert_0 said:
    And the micro rebooted and called the application. I was not able to see these messages:

    Please check if CONFIG_SERIAL is enabled in your mcuboot build:

    Albert_0 said:
    My question now is... where do I find information on how to trigger MCUBoot to stay in bootloader mode? Do I need to erase the "rsp" structure perhaps, set a variable somewhere? Ah, yes, I forgot to mention, I have no physical access to the PCB in form of buttons or other.

    FW updates are received and stored in the secondary slot by the application, not the bootloader.  The bootloader is only responsible for validating and activating the update on next reboot. It is possible to perform a FW update within the bootloader, but this is limited to serial DFU. The bootloader cannot receive an OTA update.

    Cheers,

    Vidar

Reply
  • Hi Alberto,

    Albert_0 said:
    I got the following warnings but ignored them:

    It's safe to ignore. Essentially, it indicates that your DFU upload speed can be configured to be faster. You can get rid of the warnings by adding CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP=y. This will increase the speed at the expense of higher memory usage.

    Albert_0 said:
    And the micro rebooted and called the application. I was not able to see these messages:

    Please check if CONFIG_SERIAL is enabled in your mcuboot build:

    Albert_0 said:
    My question now is... where do I find information on how to trigger MCUBoot to stay in bootloader mode? Do I need to erase the "rsp" structure perhaps, set a variable somewhere? Ah, yes, I forgot to mention, I have no physical access to the PCB in form of buttons or other.

    FW updates are received and stored in the secondary slot by the application, not the bootloader.  The bootloader is only responsible for validating and activating the update on next reboot. It is possible to perform a FW update within the bootloader, but this is limited to serial DFU. The bootloader cannot receive an OTA update.

    Cheers,

    Vidar

Children
  • Hey Vidar, thanks!

    I have 

    in my main application. Do you mean I need to add that into the "prj.conf" file in the mcuboot's directory? The one from "C:/ncs/v2.5.0/nrf/modules/mcuboot" (my installation path)?

    I'll try that out. 

    Regarding bluetooth... I cannot configure mcuboot to receive updates over bluetooth? Do I need to write that into my own application? In that case wouldn't it make more sense to have a standalone immutable bluetooth bootloader?

    Cheers,

    Alberto

  • Hi Alberto,

    The mcuboot project has a different set of configurations. You can check those by first selecting the MCUBoot project from Project explorer view in VS code (see screenshot in my previous reply, then select the generated .config output).

    If you need to apply configuration changes to the bootloader project, I recommend you follow the instructions here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/config_and_build/multi_image.html#permanent-configuration-changes-to-child-images. This way you avoid making changes to files in the SDK tree.

    Regarding bluetooth... I cannot configure mcuboot to receive updates over bluetooth? Do I need to write that into my own application? In that case wouldn't it make more sense to have a standalone immutable bluetooth bootloader?

    FOTA is not supported in the bootloaders we have. The application will automatically support DFU over BLE when you have selected the CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU symbol. If you connect to your device, you should now see that it is exposing a DFU service.

    Cheers,

    Vidar

  • Ok,

    By adding the lines:

    CONFIG_SERIAL=y
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y

    into mcuboot's "prj.conf" file I got the expected:

    So, thanks for that.

    Also, I can see the service on the NRF scanner:

    Again, thanks for clarifying.

    I turned on the NRF Device Manager App. When the "only devices advertising SMP UUID" checkbox is selected, I can't see my device:

    When I de-select the checkbox, I get:

    which is great, awesome!

    Now... How do I send the new firmware to it (I guess I select the file) but more important, where does the file get stored? I'm happy to read more about the memory layout, basically for the time being I'm not looking to swap memories, I'd be happy to overwrite the application with the new image... although... if the update fails, then I'm screwed. Might look into both memory spaces. 

    So, yes... where does the uploaded new image get stored in memory?

    Cheers,

    Alberto

  • Now... How do I send the new firmware to it (I guess I select the file) but more important, where does the file get stored?

    You can upload the app_update.bin from your build directory.

     https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/config_and_build/configuring_app/output_build_files.html#app-build-output-files 

    The update will be staged in the secondary slot. You can run the memory report action to see how the memory is laid out.

    It is not possible to update the app 'in-place' because the app needs to be running while receiving the update. The solution which we recommend if you are running out of memory, is to place the secondary slot in an external SPI flash. 

    Cheers,

    Vidar

  • What you say makes a lot of sense. Fortunately I should still have enough space on the flash memory to store the primary and the secondary (newly uploaded) application.

    One more thing, and I hope this is the last question, thanks very much for your help and patience. Where do I find information about how to configure the primary and the secondary memory space? Is that the pm_static.yml file? More importantly, how does MCUBoot know that the newer image is now in the secondary space?

    Cheers,

    Alberto

Related