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
- In the
UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID case, shouldAcceptTransfer() sets have_raw_command = true but does not return true.
- 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
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 ifhave_raw_commandis stillfalse:However,
have_raw_commandis only set totrueinshouldAcceptTransfer()when aUAVCAN_EQUIPMENT_ESC_RAWCOMMAND_IDbroadcast is seen:So if no such broadcast is received, the bootloader stays in bootloader mode forever, even though:
Additional issues noticed
UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_IDcase,shouldAcceptTransfer()setshave_raw_command = truebut does notreturn true."no signal"usesFAIL_REASON_BAD_CRCinstead ofFAIL_REASON_NO_SIGNAL, even thoughFAIL_REASON_NO_SIGNALis already defined inenum boot_code.How I verified it
As a test, I forced
have_raw_commandto be initialized astrue, 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_commandrequirement fromDroneCAN_boot_ok(), orReplace it with a startup timeout before jumping to the application.
Also change:
to:
Environment
have_raw_commandis forced totrue