Skip to content

Bootloader never jumps to main firmware unless have_raw_command becomes true #56

@AntonDrubetskiy

Description

@AntonDrubetskiy

I found a problem in the DroneCAN bootloader logic.

The bootloader starts normally and is visible in Mission Planner, but it never jumps to the main firmware. Mission Planner shows "no signal".

After analyzing the code, the issue appears to be related to have_raw_command.

What happens

In DroneCAN_boot_ok() the bootloader refuses to start the main firmware if have_raw_command is still false:

if (!have_raw_command) {
    set_reason(FAIL_REASON_BAD_CRC, "no signal");
    return false;
}

However, have_raw_command is only set to true in shouldAcceptTransfer() when a UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID broadcast is seen:

case UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID: {
    have_raw_command = true;
}

So if no such broadcast is received, the bootloader stays in bootloader mode forever, even though:

  • the bootloader itself is running correctly,
  • the node is visible in Mission Planner,
  • the main firmware is valid.

Additional issues noticed

  1. In the UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID case, shouldAcceptTransfer() sets have_raw_command = true but does not return true.
  2. The error code for "no signal" uses FAIL_REASON_BAD_CRC instead of FAIL_REASON_NO_SIGNAL, even though FAIL_REASON_NO_SIGNAL is already defined in enum boot_code.

How I verified it

As a test, I forced have_raw_command to be initialized as true, and then the bootloader successfully jumped to the main firmware.

This suggests that the boot condition depends entirely on have_raw_command, and that this logic may be incorrect or too strict.

Expected behavior

If the application firmware is valid and no firmware update is in progress, the bootloader should be able to jump to the main firmware without requiring UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID, or at least after a timeout.

Possible fix

  • Remove the have_raw_command requirement from DroneCAN_boot_ok(), or

  • Replace it with a startup timeout before jumping to the application.

  • Also change:

    set_reason(FAIL_REASON_BAD_CRC, "no signal");

    to:

    set_reason(FAIL_REASON_NO_SIGNAL, "no signal");

Environment

  • Bootloader starts correctly
  • Bootloader is visible in Mission Planner
  • Main firmware does not start unless have_raw_command is forced to true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions