Skip to content

Commit

Permalink
AP_Bootloader: add support for erasing external flash
Browse files Browse the repository at this point in the history
  • Loading branch information
bugobliterator authored and tridge committed Sep 1, 2021
1 parent edb590e commit a1499f9
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 1 deletion.
16 changes: 16 additions & 0 deletions Tools/AP_Bootloader/AP_Bootloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
#include "bl_protocol.h"
#include "can.h"
#include <stdio.h>
#if EXTERNAL_PROG_FLASH_MB
#include <AP_FlashIface/AP_FlashIface_JEDEC.h>
#endif

extern "C" {
int main(void);
Expand All @@ -51,6 +54,10 @@ struct boardinfo board_info = {
#define HAL_STAY_IN_BOOTLOADER_VALUE 0
#endif

#if EXTERNAL_PROG_FLASH_MB
AP_FlashIface_JEDEC ext_flash;
#endif

int main(void)
{
if (BOARD_FLASH_SIZE > 1024 && check_limit_flash_1M()) {
Expand Down Expand Up @@ -142,6 +149,15 @@ int main(void)
#endif
flash_init();


#if EXTERNAL_PROG_FLASH_MB
while (!ext_flash.init()) {
// keep trying until we get it working
// there's no future without it
chThdSleep(1000);
}
#endif

#if defined(BOOTLOADER_DEV_LIST)
while (true) {
bootloader(timeout);
Expand Down
81 changes: 80 additions & 1 deletion Tools/AP_Bootloader/bl_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
#include "support.h"
#include "can.h"
#include <AP_HAL_ChibiOS/hwdef/common/watchdog.h>

#if EXTERNAL_PROG_FLASH_MB
#include <AP_FlashIface/AP_FlashIface_JEDEC.h>
#endif
// #pragma GCC optimize("O0")


Expand Down Expand Up @@ -106,6 +108,14 @@
#define PROTO_DEBUG 0x31 // emit debug information - format not defined
#define PROTO_SET_BAUD 0x33 // baud rate on uart

// External Flash programming
#if EXTERNAL_PROG_FLASH_MB
#define PROTO_EXTF_ERASE 0x34 // Erase sectors from external flash
#define PROTO_EXTF_PROG_MULTI 0x35 // write bytes at external flash program address and increment
#define PROTO_EXTF_READ_MULTI 0x36 // read bytes at address and increment
#define PROTO_EXTF_GET_CRC 0x37 // compute & return a CRC of data in external flash
#endif

#define PROTO_PROG_MULTI_MAX 64 // maximum PROG_MULTI size
#define PROTO_READ_MULTI_MAX 255 // size of the size field

Expand Down Expand Up @@ -138,6 +148,11 @@ volatile unsigned timer[NTIMERS];
// access on STM32H7
#define RESERVE_LEAD_WORDS 8


#if EXTERNAL_PROG_FLASH_MB
extern AP_FlashIface_JEDEC ext_flash;
#endif

/*
1ms timer tick callback
*/
Expand Down Expand Up @@ -569,6 +584,70 @@ bootloader(unsigned timeout)
led_set(LED_BLINK);
break;

// program data from start of the flash
//
// command: EXTF_ERASE/<len:4>/EOC
// success reply: INSYNC/OK
// invalid reply: INSYNC/INVALID
// readback failure: INSYNC/FAILURE
//
case PROTO_EXTF_ERASE:
#if EXTERNAL_PROG_FLASH_MB
{
if (!done_sync || !CHECK_GET_DEVICE_FINISHED(done_get_device_flags)) {
// lower chance of random data on a uart triggering erase
goto cmd_bad;
}
uint32_t cmd_erase_bytes;
if (cin_word(&cmd_erase_bytes, 100)) {
goto cmd_bad;
}

// expect EOC
if (!wait_for_eoc(2)) {
goto cmd_bad;
}
uint32_t erased_bytes = 0;
uint32_t sector_number = 0;
uint8_t pct_done = 0;
if (cmd_erase_bytes > (ext_flash.get_sector_size() * ext_flash.get_sector_count())) {
uprintf("Requested to erase more than we can\n");
goto cmd_bad;
}
uprintf("Erase Command Received\n");
sync_response();
cout(&pct_done, sizeof(pct_done));
// Flash all sectors that encompass the erase_bytes
while (erased_bytes < cmd_erase_bytes) {
uint32_t delay_ms = 0, timeout_ms = 0;
if (!ext_flash.start_sector_erase(sector_number, delay_ms, timeout_ms)) {
goto cmd_fail;
}
uint32_t next_check_ms = AP_HAL::millis() + delay_ms;
while (true) {
cout(&pct_done, sizeof(pct_done));
if (AP_HAL::millis() > next_check_ms) {
if (!ext_flash.is_device_busy()) {
pct_done = erased_bytes*100/cmd_erase_bytes;
uprintf("PCT DONE: %d\n", pct_done);
break;
}
if ((AP_HAL::millis() + timeout_ms) > next_check_ms) {
// We are out of time, return error
goto cmd_fail;
}
next_check_ms = AP_HAL::millis()+delay_ms;
}
chThdSleep(chTimeMS2I(delay_ms));
}
erased_bytes += ext_flash.get_sector_size();
sector_number++;
}
}
#else
goto cmd_bad;
#endif // EXTERNAL_PROG_FLASH_MB
break;
// program bytes at current address
//
// command: PROG_MULTI/<len:1>/<data:len>/EOC
Expand Down

0 comments on commit a1499f9

Please sign in to comment.