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

MCUboot timeout during DFU

Greetings,

We have a PCB with nrf52 and nrf91 on it.

We have nrf9160 firmware with MCUBoot. The chip boots into mcuboot dfu mode when a certain pin is set to high during boot (CONFIG_BOOT_SERIAL_DETECT_PIN=21 in mcuboot.conf).
With this, we were able to create a system where nrf52 can put nrf91 into mcubot dfu mode (set pin to high, toggle reset) and then send data over uart to update the chip.
So: computer/phone -> ble -> nrf52 -> uart -> nrf91.

All of this works great, but we have some additional considerations:

It may be possible for this system to break -> lets say that the serial detect pin is left high and nrf91 is reset, but no DFU data is transmitted after.
Maybe DFU data stops being transmitted halfway through the update.

Is it possible to configure MCUboot to timeout if no data is received for a while and just boot into the application (the existing slot not modified by dfu)?

If not, this is probably doable by changing MCUboot source code -> is this recommended, and how hard would it be to implement? Any pointers?

Whole mcuboot.conf for clarity:

# Disable Zephyr console
CONFIG_UART_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_CONSOLE_HANDLER=n
CONFIG_UART_CONSOLE=n

# MCUBoot settings
CONFIG_BOOT_MAX_IMG_SECTORS=256

# MCUboot serial recovery
CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_DETECT_PORT="GPIO_0"
# for BOARD_V22 set to 27, for BOARD_V24 set to 21
CONFIG_BOOT_SERIAL_DETECT_PIN=21
CONFIG_BOOT_SERIAL_DETECT_PIN_VAL=1

# keys
### Default to RSA
CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN=2048
CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=n
CONFIG_BOOT_SIGNATURE_TYPE_ED25519=n

Regards,
Tjaž

Parents
  • Hi!

    We don't have a timeout implemented in MCUboot. 

    But if you want to implement it yourself, it looks like mynewt has something in their MCUboot, so you could use this for inspiration when modifying the source code.

    See ncs/bootloader/mcuboot/boot/mynewt/src/main.c more specifically lines 113-116 and lines 145-149.

    /* Calculate the timeout duration in OS cputime ticks. */
    static const uint32_t timeout_dur =
        MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) /
        (1000.0 / MYNEWT_VAL(OS_CPUTIME_FREQ));
    
    /* Abort the listen on timeout. */
    if (os_cputime_get32() >= start_tick + timeout_dur) {
        boot_uart_close();
        return false;
    }
    

    Best regards,

    Heidi

  • Hi,

    thanks for the provided information.

    For anyone else wondering, we ended up writing our own patch that looks like this:

    diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
    index 9f9cd15..c7a45b9 100644
    --- a/boot/boot_serial/src/boot_serial.c
    +++ b/boot/boot_serial/src/boot_serial.c
    @@ -591,7 +591,15 @@ boot_serial_start(const struct boot_uart_funcs *f)
         max_input = sizeof(in_buf);
     
         off = 0;
    +    uint64_t start = k_uptime_get();
    +    const uint64_t TIMEOUT = (60 * 60 * 1000); // 60 min
         while (1) {
    +        // timeout
    +        if(k_uptime_get() - start > TIMEOUT)
    +        {
    +            break;
    +        }
    +
             rc = f->read(in_buf + off, sizeof(in_buf) - off, &full_line);
             if (rc <= 0 && !full_line) {
                 continue;
    

    This adds a 1 hour timeout to the DFU procedure.

    Regards,
    Tjaž

Reply
  • Hi,

    thanks for the provided information.

    For anyone else wondering, we ended up writing our own patch that looks like this:

    diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
    index 9f9cd15..c7a45b9 100644
    --- a/boot/boot_serial/src/boot_serial.c
    +++ b/boot/boot_serial/src/boot_serial.c
    @@ -591,7 +591,15 @@ boot_serial_start(const struct boot_uart_funcs *f)
         max_input = sizeof(in_buf);
     
         off = 0;
    +    uint64_t start = k_uptime_get();
    +    const uint64_t TIMEOUT = (60 * 60 * 1000); // 60 min
         while (1) {
    +        // timeout
    +        if(k_uptime_get() - start > TIMEOUT)
    +        {
    +            break;
    +        }
    +
             rc = f->read(in_buf + off, sizeof(in_buf) - off, &full_line);
             if (rc <= 0 && !full_line) {
                 continue;
    

    This adds a 1 hour timeout to the DFU procedure.

    Regards,
    Tjaž

Children
No Data
Related