NuMaker bootloader with SD mode

Committer:
shliu1
Date:
Thu Feb 25 10:17:10 2021 +0800
Revision:
6:4dc994a04a99
Parent:
1:659cc7618f73
Child:
7:90af0e9f9fa4
Support the both V5.X and V6.0 for mbed os

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ccli8 1:659cc7618f73 1 #include "mbed.h"
ccli8 1:659cc7618f73 2 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M487)
ccli8 1:659cc7618f73 3 #include "NuSDBlockDevice.h"
ccli8 1:659cc7618f73 4 #else
ccli8 1:659cc7618f73 5 #include "SDBlockDevice.h"
ccli8 1:659cc7618f73 6 #endif
ccli8 1:659cc7618f73 7 #include "FATFileSystem.h"
ccli8 1:659cc7618f73 8
ccli8 1:659cc7618f73 9 #define SD_MOUNT_PATH "sd"
ccli8 1:659cc7618f73 10 #define FULL_UPDATE_FILE_PATH "/" SD_MOUNT_PATH "/" MBED_CONF_APP_UPDATE_FILE
ccli8 1:659cc7618f73 11
ccli8 1:659cc7618f73 12 #if !defined(POST_APPLICATION_ADDR)
ccli8 1:659cc7618f73 13 #error "target.restrict_size must be set for your target in mbed_app.json"
ccli8 1:659cc7618f73 14 #endif
ccli8 1:659cc7618f73 15
ccli8 1:659cc7618f73 16 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M487)
ccli8 1:659cc7618f73 17 NuSDBlockDevice sd;
ccli8 1:659cc7618f73 18 #else
ccli8 1:659cc7618f73 19 //Pin order: MOSI, MISO, SCK, CS
ccli8 1:659cc7618f73 20 SDBlockDevice sd(MBED_CONF_APP_SD_CARD_MOSI, MBED_CONF_APP_SD_CARD_MISO,
ccli8 1:659cc7618f73 21 MBED_CONF_APP_SD_CARD_SCK, MBED_CONF_APP_SD_CARD_CS);
ccli8 1:659cc7618f73 22 #endif
ccli8 1:659cc7618f73 23 FATFileSystem fs(SD_MOUNT_PATH);
ccli8 1:659cc7618f73 24 FlashIAP flash;
ccli8 1:659cc7618f73 25
ccli8 1:659cc7618f73 26 void apply_update(FILE *file, uint32_t address);
ccli8 1:659cc7618f73 27
ccli8 1:659cc7618f73 28 int main()
ccli8 1:659cc7618f73 29 {
ccli8 1:659cc7618f73 30 sd.init();
ccli8 1:659cc7618f73 31 fs.mount(&sd);
shliu1 6:4dc994a04a99 32 #ifdef MBED_MAJOR_VERSION
shliu1 6:4dc994a04a99 33 printf("Mbed OS version %d.%d.%d\r\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
shliu1 6:4dc994a04a99 34 #endif
ccli8 1:659cc7618f73 35
ccli8 1:659cc7618f73 36 FILE *file = fopen(FULL_UPDATE_FILE_PATH, "rb");
ccli8 1:659cc7618f73 37 if (file != NULL) {
ccli8 1:659cc7618f73 38 printf("Firmware update found\r\n");
ccli8 1:659cc7618f73 39
ccli8 1:659cc7618f73 40 apply_update(file, POST_APPLICATION_ADDR);
ccli8 1:659cc7618f73 41
ccli8 1:659cc7618f73 42 fclose(file);
ccli8 1:659cc7618f73 43 remove(FULL_UPDATE_FILE_PATH);
ccli8 1:659cc7618f73 44 } else {
ccli8 1:659cc7618f73 45 printf("No update found to apply\r\n");
ccli8 1:659cc7618f73 46 }
ccli8 1:659cc7618f73 47
ccli8 1:659cc7618f73 48 fs.unmount();
ccli8 1:659cc7618f73 49 sd.deinit();
ccli8 1:659cc7618f73 50
ccli8 1:659cc7618f73 51 printf("Starting application\r\n");
ccli8 1:659cc7618f73 52
ccli8 1:659cc7618f73 53 mbed_start_application(POST_APPLICATION_ADDR);
ccli8 1:659cc7618f73 54 }
ccli8 1:659cc7618f73 55
ccli8 1:659cc7618f73 56 void apply_update(FILE *file, uint32_t address)
ccli8 1:659cc7618f73 57 {
ccli8 1:659cc7618f73 58 fseek(file, 0, SEEK_END);
ccli8 1:659cc7618f73 59 long len = ftell(file);
ccli8 1:659cc7618f73 60 printf("Firmware size is %ld bytes\r\n", len);
ccli8 1:659cc7618f73 61 fseek(file, 0, SEEK_SET);
ccli8 1:659cc7618f73 62
ccli8 1:659cc7618f73 63 flash.init();
ccli8 1:659cc7618f73 64
ccli8 1:659cc7618f73 65 const uint32_t page_size = flash.get_page_size();
ccli8 1:659cc7618f73 66 char *page_buffer = new char[page_size];
ccli8 1:659cc7618f73 67 uint32_t addr = address;
ccli8 1:659cc7618f73 68 uint32_t next_sector = addr + flash.get_sector_size(addr);
ccli8 1:659cc7618f73 69 bool sector_erased = false;
ccli8 1:659cc7618f73 70 size_t pages_flashed = 0;
ccli8 1:659cc7618f73 71 uint32_t percent_done = 0;
ccli8 1:659cc7618f73 72 while (true) {
ccli8 1:659cc7618f73 73
ccli8 1:659cc7618f73 74 // Read data for this page
ccli8 1:659cc7618f73 75 memset(page_buffer, 0, sizeof(page_buffer));
ccli8 1:659cc7618f73 76 int size_read = fread(page_buffer, 1, page_size, file);
ccli8 1:659cc7618f73 77 if (size_read <= 0) {
ccli8 1:659cc7618f73 78 break;
ccli8 1:659cc7618f73 79 }
ccli8 1:659cc7618f73 80
ccli8 1:659cc7618f73 81 // Erase this page if it hasn't been erased
ccli8 1:659cc7618f73 82 if (!sector_erased) {
ccli8 1:659cc7618f73 83 flash.erase(addr, flash.get_sector_size(addr));
ccli8 1:659cc7618f73 84 sector_erased = true;
ccli8 1:659cc7618f73 85 }
ccli8 1:659cc7618f73 86
ccli8 1:659cc7618f73 87 // Program page
ccli8 1:659cc7618f73 88 flash.program(page_buffer, addr, page_size);
ccli8 1:659cc7618f73 89
ccli8 1:659cc7618f73 90 addr += page_size;
ccli8 1:659cc7618f73 91 if (addr >= next_sector) {
ccli8 1:659cc7618f73 92 next_sector = addr + flash.get_sector_size(addr);
ccli8 1:659cc7618f73 93 sector_erased = false;
ccli8 1:659cc7618f73 94 }
ccli8 1:659cc7618f73 95
ccli8 1:659cc7618f73 96 if (++pages_flashed % 3 == 0) {
ccli8 1:659cc7618f73 97 uint32_t percent_done_new = ftell(file) * 100 / len;
ccli8 1:659cc7618f73 98 if (percent_done != percent_done_new) {
ccli8 1:659cc7618f73 99 percent_done = percent_done_new;
ccli8 1:659cc7618f73 100 printf("Flashed %3ld%%\r", percent_done);
ccli8 1:659cc7618f73 101 }
ccli8 1:659cc7618f73 102 }
ccli8 1:659cc7618f73 103 }
ccli8 1:659cc7618f73 104 printf("Flashed 100%%\r\n", ftell(file), len);
ccli8 1:659cc7618f73 105
ccli8 1:659cc7618f73 106 delete[] page_buffer;
ccli8 1:659cc7618f73 107
ccli8 1:659cc7618f73 108 flash.deinit();
ccli8 1:659cc7618f73 109 }