Nuvoton
/
NuMaker-mbed-bootloader-example
NuMaker bootloader with SD mode
main.cpp@1:659cc7618f73, 2017-12-26 (annotated)
- 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?
User | Revision | Line number | New 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 | } |