NuMaker bootloader with SD mode

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M487) || defined(TARGET_NUMAKER_IOT_M467)
00003 #include "NuSDBlockDevice.h"
00004 #else
00005 #include "SDBlockDevice.h"
00006 #endif
00007 #include "FlashSimBlockDevice.h"
00008 #include "FATFileSystem.h"
00009 
00010 #define SD_MOUNT_PATH           "sd"
00011 #define FULL_UPDATE_FILE_PATH   "/" SD_MOUNT_PATH "/" MBED_CONF_APP_UPDATE_FILE
00012 
00013 #if !defined(POST_APPLICATION_ADDR)
00014 #error "target.restrict_size must be set for your target in mbed_app.json"
00015 #endif
00016 
00017 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M487) || defined(TARGET_NUMAKER_IOT_M467)
00018 NuSDBlockDevice *bd_ = new NuSDBlockDevice();
00019 // Add flash-simulate layer on top of NUSD not implementing "erase" characteristic
00020 FlashSimBlockDevice *bd = new FlashSimBlockDevice(bd_);
00021 #else
00022 //Pin order: MOSI, MISO, SCK, CS
00023 SDBlockDevice sd(MBED_CONF_APP_SD_CARD_MOSI, MBED_CONF_APP_SD_CARD_MISO,
00024                  MBED_CONF_APP_SD_CARD_SCK, MBED_CONF_APP_SD_CARD_CS);
00025 #endif
00026 FATFileSystem fs(SD_MOUNT_PATH);
00027 FlashIAP flash;
00028 
00029 void apply_update(FILE *file, uint32_t address);
00030 
00031 int main()
00032 {
00033     int err = fs.mount(bd);
00034 #ifdef MBED_MAJOR_VERSION
00035     printf("Mbed OS version %d.%d.%d\r\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
00036 #endif
00037 
00038     FILE *file = fopen(FULL_UPDATE_FILE_PATH, "rb");
00039     if (file != NULL) {
00040         printf("Firmware update found\r\n");
00041 
00042         apply_update(file, POST_APPLICATION_ADDR);
00043 
00044         fclose(file);
00045         remove(FULL_UPDATE_FILE_PATH);
00046     } else {
00047         printf("No update found to apply\r\n");
00048     }
00049 
00050     fs.unmount();
00051  
00052     printf("Starting application\r\n");
00053 
00054     mbed_start_application(POST_APPLICATION_ADDR);
00055 }
00056 
00057 void apply_update(FILE *file, uint32_t address)
00058 {
00059     fseek(file, 0, SEEK_END);
00060     long len = ftell(file);
00061     printf("Firmware size is %ld bytes\r\n", len);
00062     fseek(file, 0, SEEK_SET);
00063   
00064     flash.init();
00065 
00066     const uint32_t page_size = flash.get_page_size();
00067     char *page_buffer = new char[page_size];
00068     uint32_t addr = address;
00069     uint32_t next_sector = addr + flash.get_sector_size(addr);
00070     bool sector_erased = false;
00071     size_t pages_flashed = 0;
00072     uint32_t percent_done = 0;
00073     while (true) {
00074 
00075         // Read data for this page
00076         memset(page_buffer, 0, sizeof(page_buffer));
00077         int size_read = fread(page_buffer, 1, page_size, file);
00078         if (size_read <= 0) {
00079             break;
00080         }
00081 
00082         // Erase this page if it hasn't been erased
00083         if (!sector_erased) {
00084             flash.erase(addr, flash.get_sector_size(addr));
00085             sector_erased = true;
00086         }
00087 
00088         // Program page
00089         flash.program(page_buffer, addr, page_size);
00090 
00091         addr += page_size;
00092         if (addr >= next_sector) {
00093             next_sector = addr + flash.get_sector_size(addr);
00094             sector_erased = false;
00095         }
00096 
00097         if (++pages_flashed % 3 == 0) {
00098             uint32_t percent_done_new = ftell(file) * 100 / len;
00099             if (percent_done != percent_done_new) {
00100                 percent_done = percent_done_new;
00101                 printf("Flashed %3ld%%\r", percent_done);
00102             }
00103         }
00104     }
00105     printf("Flashed 100%%\r\n", ftell(file), len);
00106 
00107     delete[] page_buffer;
00108 
00109     flash.deinit();
00110 }