Nuvoton
/
NuMaker-mbed-bootloader-example
NuMaker bootloader with SD mode
main.cpp@7:90af0e9f9fa4, 18 months ago (annotated)
- 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?
User | Revision | Line number | New 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 | } |