bootloader: implement WipeDevice

This commit is contained in:
Pavol Rusnak 2017-10-16 20:24:28 +02:00
parent 5bec30e0dc
commit 82050912c4
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
7 changed files with 130 additions and 20 deletions

View File

@ -42,7 +42,7 @@ static uint32_t check_sdcard(void)
}
}
static void progress_callback(uint16_t val) {
static void progress_callback(int pos, int len) {
display_printf(".");
}
@ -72,7 +72,30 @@ static bool copy_sdcard(void)
display_printf("\n\nerasing flash:\n\n");
// erase all flash (except boardloader)
if (!flash_erase_sectors(FLASH_SECTOR_BOARDLOADER_END + 1, FLASH_SECTOR_LAST, progress_callback)) {
uint8_t sectors[] = {
FLASH_SECTOR_STORAGE_1,
FLASH_SECTOR_STORAGE_2,
FLASH_SECTOR_PIN_AREA,
FLASH_SECTOR_BOOTLOADER,
FLASH_SECTOR_FIRMWARE_START,
7,
8,
9,
10,
FLASH_SECTOR_FIRMWARE_END,
FLASH_SECTOR_UNUSED_START,
13,
14,
FLASH_SECTOR_UNUSED_END,
FLASH_SECTOR_FIRMWARE_EXTRA_START,
18,
19,
20,
21,
22,
FLASH_SECTOR_FIRMWARE_EXTRA_END,
};
if (!flash_erase_sectors(sectors, 2 + 1 + 1 + 6 + 4 + 7, progress_callback)) {
display_printf(" failed\n");
return false;
}
@ -130,8 +153,8 @@ int main(void)
#if PRODUCTION
flash_set_option_bytes();
if (!flash_check_option_bytes()) {
flash_erase_sectors(FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_1, NULL);
flash_erase_sectors(FLASH_SECTOR_STORAGE_2, FLASH_SECTOR_STORAGE_2, NULL);
uint8_t sectors[] = {FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2};
flash_erase_sectors(sectors, 2, NULL);
ensure(0, "wrong option bytes");
}
#endif

View File

@ -144,19 +144,36 @@ void bootloader_loop(void)
case 1: // Ping
process_msg_Ping(USB_IFACE_NUM, msg_size, buf);
break;
case 5: // WipeDevice
display_clear();
display_text_center(120, 30, "Wiping Device", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
if (r < 0) { // error
display_clear();
display_text_center(120, 30, "Error", -1, FONT_BOLD, COLOR_RED, COLOR_BLACK);
display_loader(1000, 0, COLOR_RED, COLOR_BLACK, 0, 0, 0);
} else { // success
display_clear();
display_text_center(120, 30, "Done", -1, FONT_BOLD, COLOR_GREEN, COLOR_BLACK);
display_loader(1000, 0, COLOR_GREEN, COLOR_BLACK, 0, 0, 0);
}
break;
case 6: // FirmwareErase
display_text_center(120, 230, "Updating firmware", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
display_clear();
display_text_center(120, 30, "Updating Firmware", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
break;
case 7: // FirmwareUpload
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
if (r < 0) { // error
display_clear();
display_text_center(120, 230, "Error", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
display_text_center(120, 30, "Error", -1, FONT_BOLD, COLOR_RED, COLOR_BLACK);
display_loader(1000, 0, COLOR_RED, COLOR_BLACK, 0, 0, 0);
} else
if (r == 0) { // last chunk received
display_clear();
display_text_center(120, 230, "Done", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
display_text_center(120, 30, "Done", -1, FONT_BOLD, COLOR_GREEN, COLOR_BLACK);
display_loader(1000, 0, COLOR_GREEN, COLOR_BLACK, 0, 0, 0);
}
break;
default:
@ -201,13 +218,16 @@ int main(void)
ensure(0 == touch_init(), NULL);
uint32_t touched = 0;
for (int i = 0; i < 10; i++) {
touched |= touch_read();
// delay to detect touch
hal_delay(100);
bool touched = false;
// flush touch events
while (touch_read()) {
touched = true;
}
// start the bootloader if user touched the screen or no firmware installed
if (touched != 0 || !vendor_parse_header((const uint8_t *)FIRMWARE_START, NULL)) {
if (touched || !vendor_parse_header((const uint8_t *)FIRMWARE_START, NULL)) {
bootloader_loop();
shutdown();
}

View File

@ -228,9 +228,9 @@ void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
static uint32_t firmware_remaining, firmware_flashed, chunk_requested;
static void progress_erase(uint16_t val)
static void progress_erase(int pos, int len)
{
display_loader(val / 4, 0, 0xFFFF, 0, 0, 0, 0);
display_loader(250 * pos / len, 0, COLOR_WHITE, COLOR_BLACK, 0, 0, 0);
}
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
@ -245,7 +245,22 @@ void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
firmware_remaining = msg_recv.has_length ? msg_recv.length : 0;
if (firmware_remaining > 0 && firmware_remaining % 4 == 0) {
// erase flash
if (!flash_erase_sectors(FLASH_SECTOR_FIRMWARE_START, FLASH_SECTOR_FIRMWARE_END, progress_erase)) {
uint8_t sectors[] = {
FLASH_SECTOR_FIRMWARE_START,
7,
8,
9,
10,
FLASH_SECTOR_FIRMWARE_END,
FLASH_SECTOR_FIRMWARE_EXTRA_START,
18,
19,
20,
21,
22,
FLASH_SECTOR_FIRMWARE_EXTRA_END,
};
if (!flash_erase_sectors(sectors, 6 + 7, progress_erase)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");
@ -276,7 +291,7 @@ static bool _read_payload(pb_istream_t *stream, const pb_field_t *field, void **
chunk_size = stream->bytes_left;
while (stream->bytes_left) {
// print loader
display_loader(250 + 750 * (firmware_flashed + chunk_written) / (firmware_flashed + firmware_remaining), 0, 0xFFFF, 0, 0, 0, 0);
display_loader(250 + 750 * (firmware_flashed + chunk_written) / (firmware_flashed + firmware_remaining), 0, COLOR_WHITE, COLOR_BLACK, 0, 0, 0);
memset(buf, 0xFF, sizeof(buf));
// read data
if (!pb_read(stream, (pb_byte_t *)buf, (stream->bytes_left > BUFSIZE) ? BUFSIZE : stream->bytes_left)) {
@ -331,6 +346,48 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
return (int)firmware_remaining;
}
static void progress_wipe(int pos, int len)
{
display_loader(1000 * pos / len, 0, COLOR_WHITE, COLOR_BLACK, 0, 0, 0);
}
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
uint8_t sectors[] = {
FLASH_SECTOR_STORAGE_1,
FLASH_SECTOR_STORAGE_2,
FLASH_SECTOR_PIN_AREA,
FLASH_SECTOR_FIRMWARE_START,
7,
8,
9,
10,
FLASH_SECTOR_FIRMWARE_END,
FLASH_SECTOR_UNUSED_START,
13,
14,
FLASH_SECTOR_UNUSED_END,
FLASH_SECTOR_FIRMWARE_EXTRA_START,
18,
19,
20,
21,
22,
FLASH_SECTOR_FIRMWARE_EXTRA_END,
};
if (!flash_erase_sectors(sectors, 2 + 1 + 6 + 4 + 7, progress_wipe)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");
MSG_SEND(Failure);
return -1;
} else {
MSG_SEND_INIT(Success);
MSG_SEND(Success);
return 0;
}
}
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
// consume remaining message

View File

@ -13,6 +13,7 @@ void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
#endif

View File

@ -38,8 +38,14 @@
#define COLOR_GRAY128 RGB16(127, 127, 127)
#define COLOR_GRAY64 RGB16(63, 63, 63)
#define COLOR_BLACK RGB16(0, 0, 0)
#define COLOR_RED RGB16(255, 0, 0)
#define COLOR_RED128 RGB16(127, 0, 0)
#define COLOR_GREEN RGB16(0, 255, 0)
#define COLOR_GREEN128 RGB16(0, 127, 0)
#define COLOR_BLUE RGB16(0, 0, 255)
#define COLOR_BLUE128 RGB16(0, 0, 127)
// provided by port

View File

@ -21,7 +21,7 @@ bool flash_lock(void)
return true;
}
bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val))
bool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int pos, int len))
{
if (!flash_unlock()) {
return false;
@ -31,14 +31,17 @@ bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val))
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.NbSectors = 1;
uint32_t SectorError = 0;
for (int i = start; i <= end; i++) {
EraseInitStruct.Sector = i;
if (progress) {
progress(0, len);
}
for (int i = 0; i < len; i++) {
EraseInitStruct.Sector = sectors[i];
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
flash_lock();
return false;
}
if (progress) {
progress(1000 * (i - start + 1) / (end - start + 1));
progress(i + 1, len);
}
}
flash_lock();

View File

@ -47,7 +47,7 @@ void flash_set_option_bytes(void);
bool flash_unlock(void);
bool flash_lock(void);
bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val));
bool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int pos, int len));
bool flash_write_byte(uint32_t address, uint8_t data);
bool flash_write_word(uint32_t address, uint32_t data);