NuMaker bootloader with SD mode

Committer:
cyliang
Date:
Mon Mar 13 02:08:34 2023 +0000
Revision:
7:90af0e9f9fa4
Parent:
6:4dc994a04a99
Update main.cpp, SD lib & OS to v6.17.0

Who changed what in which revision?

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