Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support booting px4 can fw using ArduPilot bootloader #20001

Merged
merged 7 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Tools/AP_Bootloader/AP_Bootloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ int main(void)
timeout = 10000;
can_set_node_id(m & 0xFF);
}
can_check_update();
if (can_check_update()) {
// trying to update firmware, stay in bootloader
try_boot = false;
timeout = 0;
}
if (!can_check_firmware()) {
// bad firmware CRC, don't try and boot
timeout = 0;
Expand Down
56 changes: 52 additions & 4 deletions Tools/AP_Bootloader/can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,12 @@ bool can_check_firmware(void)
return false;
}

if (ad->board_id != APJ_BOARD_ID) {
bool id_ok = (ad->board_id == APJ_BOARD_ID);
#ifdef ALT_BOARD_ID
id_ok |= (ad->board_id == ALT_BOARD_ID);
#endif

if (!id_ok) {
node_status.vendor_specific_status_code = FAIL_REASON_BAD_BOARD_ID;
printf("Bad board_id %u should be %u\n", ad->board_id, APJ_BOARD_ID);
return false;
Expand All @@ -678,18 +683,61 @@ bool can_check_firmware(void)
}

// check for a firmware update marker left by app
void can_check_update(void)
bool can_check_update(void)
{
bool ret = false;
#if HAL_RAM_RESERVE_START >= 256
struct app_bootloader_comms *comms = (struct app_bootloader_comms *)HAL_RAM0_START;
if (comms->magic == APP_BOOTLOADER_COMMS_MAGIC) {
can_set_node_id(comms->my_node_id);
fw_update.node_id = comms->server_node_id;
memcpy(fw_update.path, comms->path, UAVCAN_PROTOCOL_FILE_PATH_PATH_MAX_LENGTH+1);
ret = true;
// clear comms region
memset(comms, 0, sizeof(struct app_bootloader_comms));
}
#endif
#if defined(CAN1_BASE) && defined(RCC_APB1ENR_CAN1EN)
// check for px4 fw update. px4 uses the filter registers in CAN1
// to communicate with the bootloader. This only works on CAN1
if (!ret && stm32_was_software_reset()) {
uint32_t *fir = (uint32_t *)(CAN1_BASE + 0x240);
struct PACKED app_shared {
union {
uint64_t ull;
uint32_t ul[2];
uint8_t valid;
} crc;
uint32_t signature;
uint32_t bus_speed;
uint32_t node_id;
} *app = (struct app_shared *)&fir[4];
/* we need to enable the CAN peripheral in order to look at
the FIR registers.
*/
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
static const uint32_t app_signature = 0xb0a04150;
if (app->signature == app_signature &&
app->node_id > 0 && app->node_id < 128) {
// crc is in reversed word order in FIR registers
uint32_t sig[3];
memcpy((uint8_t *)&sig[0], (const uint8_t *)&app->signature, sizeof(sig));
const uint64_t crc = crc_crc64(sig, 3);
const uint32_t *crc32 = (const uint32_t *)&crc;
if (crc32[0] == app->crc.ul[1] &&
crc32[1] == app->crc.ul[0]) {
// reset signature so we don't get in a boot loop
app->signature = 0;
// setup node ID
can_set_node_id(app->node_id);
// and baudrate
baudrate = app->bus_speed;
ret = true;
}
}
}
// clear comms region
memset(comms, 0, sizeof(struct app_bootloader_comms));
#endif
return ret;
}

void can_start()
Expand Down
2 changes: 1 addition & 1 deletion Tools/AP_Bootloader/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ void can_start();
void can_update();
void can_set_node_id(uint8_t node_id);
bool can_check_firmware(void);
void can_check_update(void);
bool can_check_update(void);
Binary file added Tools/bootloaders/ARK_GPS_bl.bin
Binary file not shown.
Loading