NuMaker bootloader with SD mode

Committer:
ccli8
Date:
Tue Dec 26 11:08:40 2017 +0800
Revision:
1:659cc7618f73
Child:
6:4dc994a04a99
Support NUMAKER_PFM_NUC472 and NUMAKER_PFM_M487

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);
ccli8 1:659cc7618f73 32
ccli8 1:659cc7618f73 33 FILE *file = fopen(FULL_UPDATE_FILE_PATH, "rb");
ccli8 1:659cc7618f73 34 if (file != NULL) {
ccli8 1:659cc7618f73 35 printf("Firmware update found\r\n");
ccli8 1:659cc7618f73 36
ccli8 1:659cc7618f73 37 apply_update(file, POST_APPLICATION_ADDR);
ccli8 1:659cc7618f73 38
ccli8 1:659cc7618f73 39 fclose(file);
ccli8 1:659cc7618f73 40 remove(FULL_UPDATE_FILE_PATH);
ccli8 1:659cc7618f73 41 } else {
ccli8 1:659cc7618f73 42 printf("No update found to apply\r\n");
ccli8 1:659cc7618f73 43 }
ccli8 1:659cc7618f73 44
ccli8 1:659cc7618f73 45 fs.unmount();
ccli8 1:659cc7618f73 46 sd.deinit();
ccli8 1:659cc7618f73 47
ccli8 1:659cc7618f73 48 printf("Starting application\r\n");
ccli8 1:659cc7618f73 49
ccli8 1:659cc7618f73 50 mbed_start_application(POST_APPLICATION_ADDR);
ccli8 1:659cc7618f73 51 }
ccli8 1:659cc7618f73 52
ccli8 1:659cc7618f73 53 void apply_update(FILE *file, uint32_t address)
ccli8 1:659cc7618f73 54 {
ccli8 1:659cc7618f73 55 fseek(file, 0, SEEK_END);
ccli8 1:659cc7618f73 56 long len = ftell(file);
ccli8 1:659cc7618f73 57 printf("Firmware size is %ld bytes\r\n", len);
ccli8 1:659cc7618f73 58 fseek(file, 0, SEEK_SET);
ccli8 1:659cc7618f73 59
ccli8 1:659cc7618f73 60 flash.init();
ccli8 1:659cc7618f73 61
ccli8 1:659cc7618f73 62 const uint32_t page_size = flash.get_page_size();
ccli8 1:659cc7618f73 63 char *page_buffer = new char[page_size];
ccli8 1:659cc7618f73 64 uint32_t addr = address;
ccli8 1:659cc7618f73 65 uint32_t next_sector = addr + flash.get_sector_size(addr);
ccli8 1:659cc7618f73 66 bool sector_erased = false;
ccli8 1:659cc7618f73 67 size_t pages_flashed = 0;
ccli8 1:659cc7618f73 68 uint32_t percent_done = 0;
ccli8 1:659cc7618f73 69 while (true) {
ccli8 1:659cc7618f73 70
ccli8 1:659cc7618f73 71 // Read data for this page
ccli8 1:659cc7618f73 72 memset(page_buffer, 0, sizeof(page_buffer));
ccli8 1:659cc7618f73 73 int size_read = fread(page_buffer, 1, page_size, file);
ccli8 1:659cc7618f73 74 if (size_read <= 0) {
ccli8 1:659cc7618f73 75 break;
ccli8 1:659cc7618f73 76 }
ccli8 1:659cc7618f73 77
ccli8 1:659cc7618f73 78 // Erase this page if it hasn't been erased
ccli8 1:659cc7618f73 79 if (!sector_erased) {
ccli8 1:659cc7618f73 80 flash.erase(addr, flash.get_sector_size(addr));
ccli8 1:659cc7618f73 81 sector_erased = true;
ccli8 1:659cc7618f73 82 }
ccli8 1:659cc7618f73 83
ccli8 1:659cc7618f73 84 // Program page
ccli8 1:659cc7618f73 85 flash.program(page_buffer, addr, page_size);
ccli8 1:659cc7618f73 86
ccli8 1:659cc7618f73 87 addr += page_size;
ccli8 1:659cc7618f73 88 if (addr >= next_sector) {
ccli8 1:659cc7618f73 89 next_sector = addr + flash.get_sector_size(addr);
ccli8 1:659cc7618f73 90 sector_erased = false;
ccli8 1:659cc7618f73 91 }
ccli8 1:659cc7618f73 92
ccli8 1:659cc7618f73 93 if (++pages_flashed % 3 == 0) {
ccli8 1:659cc7618f73 94 uint32_t percent_done_new = ftell(file) * 100 / len;
ccli8 1:659cc7618f73 95 if (percent_done != percent_done_new) {
ccli8 1:659cc7618f73 96 percent_done = percent_done_new;
ccli8 1:659cc7618f73 97 printf("Flashed %3ld%%\r", percent_done);
ccli8 1:659cc7618f73 98 }
ccli8 1:659cc7618f73 99 }
ccli8 1:659cc7618f73 100 }
ccli8 1:659cc7618f73 101 printf("Flashed 100%%\r\n", ftell(file), len);
ccli8 1:659cc7618f73 102
ccli8 1:659cc7618f73 103 delete[] page_buffer;
ccli8 1:659cc7618f73 104
ccli8 1:659cc7618f73 105 flash.deinit();
ccli8 1:659cc7618f73 106 }