Custom MCUboot DFU bootloader nrf Connect

Hi,

We want to modify the bootloader process on MCUboot. To avoid someone having to press and hold a button the entire time on our custom boards we want as a minimum to set a pin high to ensure it doesn't turn off.

I was successfully able to try this using SYS_INIT and a custom board.c file by following this ticket  Modify the MCUboot's booting process however, the problem I've found with this method is it sets the pin high regardless of whether the unit goes through the bootloader or not - which makes sense. In some instances we want to indicate the bootloader is running by switching on an LED just as user feedback something's going on. So a potential flicker of the LED (e.g. switching it off ASAP in the main app) would be inappropriate for our devices. 

It looks therefore that the best way to achieve what we want is by modifying the bootloader and I've gone down a ticket rabbit hole through here  How to create custom MCUBOOT for DFU which ends up leading to this blog archive:  nRF Connect SDK Tutorial - Part 2 | NCS v1.3.0 

is there a more up to date and recommended way of customising the mcuboot? Our aim would be to have a file within the main project directory that handles the main functions of the boot but adds in our own "switch on this pin" code.

Thanks.

BR,
Richard

Parents Reply
  • That looks promising. Where does the handler for mcuboot_status_change need to be placed?

    I've added it in the main project directory at the moment (which I suspected would be wrong), I'm getting this in the build log:

    c:/ncs/toolchains/v2.1.2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.3.0/../../../../arm-zephyr-eabi/bin/ld.exe: app/libapp.a(loader.c.obj): in function `context_boot_go':
    C:\ncs\v2.1.2\bootloader\mcuboot\boot\bootutil\src\loader.c:2112: undefined reference to `mcuboot_status_change'
    collect2.exe: error: ld returned 1 exit status

    I added 

    CONFIG_MCUBOOT_ACTION_HOOKS=y into my mcuboot.conf file which is within a child_image folder.
Children
  • Hi,

    I haven't tested it, but I'm thinking that you in CMakeLists.txt in boards/arm/your_board , can add something like this:

    if(CONFIG_MCUBOOT)
    zephyr_library()
    zephyr_library_sources(my_mcuboot_hook.c)
    endif()

    Then place a my_mcuboot_hook.c in boards/arm/your_board

    Might need to include these:

    #include "bootutil/boot_hooks.h"
    #include "bootutil/mcuboot_status.h"

  • Thank you, I've got that running. Unfortunately, not exactly how I was expecting.

    I realise I didn't mention we're doing the upgrade via bluetooth and nrf Connect google play store app. The lack of MCUBOOT_STATUS references to BLE types seem to indicate those status updates aren't supported?

    In which case, it's basically back to the initial query on the best process for this?

    I've added this:

    void mcuboot_status_change(mcuboot_status_type_t status)
    {
    	printk("mcuboot status: %d \n", status);
    }

    and my terminal output is below (emphasis mine). Perhaps my misunderstanding, but I wouldn't expect the 'normal' startup process to hit the status of 1 (MCUBOOT_STATUS_UPGRADING)?

    *** Booting Zephyr OS build v3.1.99-ncs1-1 ***
    I: Starting bootloader
    mcuboot status: 0
    I: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x1
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    mcuboot status: 1
    I: Bootloader chainload address offset: 0xc000
    I: Jumping to the first image slot
    *** Booting Zephyr OS build v3.1.99-ncs1-1 ***
    Bluetooth initialized
    Advertising successfully started
    build time: Nov 30 2022 12:23:46


    uart:~$ Connected
    [00:00:26.260,498] <inf> mcuboot_util: Swap type: none
    [00:00:26.260,772] <inf> mcuboot_util: Swap type: none
    [00:00:26.412,780] <inf> mcuboot_util: Swap type: none
    [00:00:26.412,872] <inf> mcuboot_util: Swap type: none
    [00:00:34.729,522] <inf> mcumgr_img_mgmt: Erased 0x39000 bytes of image slot
    [00:00:34.875,823] <inf> mcumgr_img_mgmt: Erased 0x1000 bytes of image slot trailer
    uart:~$ *** Booting Zephyr OS build v3.1.99-ncs1-1 ***
    I: Starting bootloader
    mcuboot status: 0
    I: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x1
    I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: test
    mcuboot status: 1
    I: Starting swap using move algorithm.
    I: Bootloader chainload address offset: 0xc000
    I: Jumping to the first image slot
    *** Booting Zephyr OS build v3.1.99-ncs1-1 ***
    Bluetooth initialized
    Advertising successfully started
    build time: Nov 30 2022 12:01:21


    uart:~$ Connected
    [00:00:01.227,844] <inf> mcuboot_util: Swap type: revert
    [00:00:01.227,905] <inf> mcuboot_util: Swap type: revert
    [00:00:01.228,546] <inf> mcuboot_util: Swap type: none
    [00:00:01.228,820] <inf> mcuboot_util: Swap type: none
    uart:~$

  • Hi,

    I checked this with the developer, MCUBOOT_STATUS_UPGRADING does not necessarily mean that it is upgrading the image, just that it is at the point of mcuboot where upgrades take place... https://github.com/zephyrproject-rtos/mcuboot/blob/main/boot/bootutil/src/loader.c#L2059

    to make it only run if an upgrade is present, it could be placed in an if()

    PS: It might be getting cut off due to booting the application but the status does change prior to the application booting: mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND);

  • to make it only run if an upgrade is present, it could be placed in an if()

    Excuse my ignorance, but which part exactly would be placed in an if, and what's being checked?

    I'm already doing this:

    if(CONFIG_MCUBOOT)
    zephyr_library()
    zephyr_library_sources(my_mcuboot_hook.c)
    endif()

    BR,
    Richard

  • Richard said:
    Excuse my ignorance, but which part exactly would be placed in an if, and what's being checked?

    Something like this at https://github.com/zephyrproject-rtos/mcuboot/blob/main/boot/bootutil/src/loader.c#L2059

    if(has_upgrade) {
        mcuboot_status_change(MCUBOOT_STATUS_UPGRADING);
    
    }

    Some other alternatives that might work is to use boot_perform_update_hook() instead

    https://github.com/nrfconnect/sdk-mcuboot/blob/main/boot/zephyr/hooks_sample.c

Related