Stefano Mammolito
/
mbed-os-bootloader-F411
Simple F411 bootloader.
main.cpp@0:cd3dd72a93f5, 2018-04-10 (annotated)
- Committer:
- stema
- Date:
- Tue Apr 10 08:52:17 2018 +0000
- Revision:
- 0:cd3dd72a93f5
Simple F411 SD bootloader.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
stema | 0:cd3dd72a93f5 | 1 | #include "SDBlockDevice.h" |
stema | 0:cd3dd72a93f5 | 2 | #include "FATFileSystem.h" |
stema | 0:cd3dd72a93f5 | 3 | |
stema | 0:cd3dd72a93f5 | 4 | #define SD_MOUNT_PATH "sd" |
stema | 0:cd3dd72a93f5 | 5 | #define FULL_UPDATE_FILE_PATH "/" SD_MOUNT_PATH "/blinky.bin" |
stema | 0:cd3dd72a93f5 | 6 | |
stema | 0:cd3dd72a93f5 | 7 | #define POST_APPLICATION_ADDR 0x08020000 |
stema | 0:cd3dd72a93f5 | 8 | |
stema | 0:cd3dd72a93f5 | 9 | #if !defined(POST_APPLICATION_ADDR) |
stema | 0:cd3dd72a93f5 | 10 | #error "target.restrict_size must be set for your target in mbed_app.json" |
stema | 0:cd3dd72a93f5 | 11 | #endif |
stema | 0:cd3dd72a93f5 | 12 | |
stema | 0:cd3dd72a93f5 | 13 | //Pin order: MOSI, MISO, SCK, CS |
stema | 0:cd3dd72a93f5 | 14 | SDBlockDevice sd(SPI_MOSI, SPI_MISO, |
stema | 0:cd3dd72a93f5 | 15 | SPI_SCK, SPI_CS); |
stema | 0:cd3dd72a93f5 | 16 | FATFileSystem fs(SD_MOUNT_PATH); |
stema | 0:cd3dd72a93f5 | 17 | FlashIAP flash; |
stema | 0:cd3dd72a93f5 | 18 | |
stema | 0:cd3dd72a93f5 | 19 | void apply_update(FILE *file, uint32_t address); |
stema | 0:cd3dd72a93f5 | 20 | |
stema | 0:cd3dd72a93f5 | 21 | int main() |
stema | 0:cd3dd72a93f5 | 22 | { |
stema | 0:cd3dd72a93f5 | 23 | sd.init(); |
stema | 0:cd3dd72a93f5 | 24 | fs.mount(&sd); |
stema | 0:cd3dd72a93f5 | 25 | |
stema | 0:cd3dd72a93f5 | 26 | FILE *file = fopen(FULL_UPDATE_FILE_PATH, "rb"); |
stema | 0:cd3dd72a93f5 | 27 | if (file != NULL) { |
stema | 0:cd3dd72a93f5 | 28 | printf("Firmware update found\r\n"); |
stema | 0:cd3dd72a93f5 | 29 | |
stema | 0:cd3dd72a93f5 | 30 | apply_update(file, POST_APPLICATION_ADDR); |
stema | 0:cd3dd72a93f5 | 31 | |
stema | 0:cd3dd72a93f5 | 32 | fclose(file); |
stema | 0:cd3dd72a93f5 | 33 | remove(FULL_UPDATE_FILE_PATH); |
stema | 0:cd3dd72a93f5 | 34 | } else { |
stema | 0:cd3dd72a93f5 | 35 | printf("No update found to apply\r\n"); |
stema | 0:cd3dd72a93f5 | 36 | } |
stema | 0:cd3dd72a93f5 | 37 | |
stema | 0:cd3dd72a93f5 | 38 | fs.unmount(); |
stema | 0:cd3dd72a93f5 | 39 | sd.deinit(); |
stema | 0:cd3dd72a93f5 | 40 | |
stema | 0:cd3dd72a93f5 | 41 | printf("Starting application\r\n"); |
stema | 0:cd3dd72a93f5 | 42 | |
stema | 0:cd3dd72a93f5 | 43 | mbed_start_application(POST_APPLICATION_ADDR); |
stema | 0:cd3dd72a93f5 | 44 | } |
stema | 0:cd3dd72a93f5 | 45 | |
stema | 0:cd3dd72a93f5 | 46 | void apply_update(FILE *file, uint32_t address) |
stema | 0:cd3dd72a93f5 | 47 | { |
stema | 0:cd3dd72a93f5 | 48 | fseek(file, 0, SEEK_END); |
stema | 0:cd3dd72a93f5 | 49 | long len = ftell(file); |
stema | 0:cd3dd72a93f5 | 50 | printf("Firmware size is %ld bytes\r\n", len); |
stema | 0:cd3dd72a93f5 | 51 | fseek(file, 0, SEEK_SET); |
stema | 0:cd3dd72a93f5 | 52 | |
stema | 0:cd3dd72a93f5 | 53 | flash.init(); |
stema | 0:cd3dd72a93f5 | 54 | |
stema | 0:cd3dd72a93f5 | 55 | const uint32_t page_size = flash.get_page_size(); |
stema | 0:cd3dd72a93f5 | 56 | char *page_buffer = new char[page_size]; |
stema | 0:cd3dd72a93f5 | 57 | uint32_t addr = address; |
stema | 0:cd3dd72a93f5 | 58 | uint32_t next_sector = addr + flash.get_sector_size(addr); |
stema | 0:cd3dd72a93f5 | 59 | bool sector_erased = false; |
stema | 0:cd3dd72a93f5 | 60 | size_t pages_flashed = 0; |
stema | 0:cd3dd72a93f5 | 61 | uint32_t percent_done = 0; |
stema | 0:cd3dd72a93f5 | 62 | while (true) { |
stema | 0:cd3dd72a93f5 | 63 | |
stema | 0:cd3dd72a93f5 | 64 | // Read data for this page |
stema | 0:cd3dd72a93f5 | 65 | memset(page_buffer, 0, sizeof(page_buffer)); |
stema | 0:cd3dd72a93f5 | 66 | int size_read = fread(page_buffer, 1, page_size, file); |
stema | 0:cd3dd72a93f5 | 67 | if (size_read <= 0) { |
stema | 0:cd3dd72a93f5 | 68 | break; |
stema | 0:cd3dd72a93f5 | 69 | } |
stema | 0:cd3dd72a93f5 | 70 | |
stema | 0:cd3dd72a93f5 | 71 | // Erase this page if it hasn't been erased |
stema | 0:cd3dd72a93f5 | 72 | if (!sector_erased) { |
stema | 0:cd3dd72a93f5 | 73 | flash.erase(addr, flash.get_sector_size(addr)); |
stema | 0:cd3dd72a93f5 | 74 | sector_erased = true; |
stema | 0:cd3dd72a93f5 | 75 | } |
stema | 0:cd3dd72a93f5 | 76 | |
stema | 0:cd3dd72a93f5 | 77 | // Program page |
stema | 0:cd3dd72a93f5 | 78 | flash.program(page_buffer, addr, page_size); |
stema | 0:cd3dd72a93f5 | 79 | |
stema | 0:cd3dd72a93f5 | 80 | addr += page_size; |
stema | 0:cd3dd72a93f5 | 81 | if (addr >= next_sector) { |
stema | 0:cd3dd72a93f5 | 82 | next_sector = addr + flash.get_sector_size(addr); |
stema | 0:cd3dd72a93f5 | 83 | sector_erased = false; |
stema | 0:cd3dd72a93f5 | 84 | } |
stema | 0:cd3dd72a93f5 | 85 | |
stema | 0:cd3dd72a93f5 | 86 | if (++pages_flashed % 3 == 0) { |
stema | 0:cd3dd72a93f5 | 87 | uint32_t percent_done_new = ftell(file) * 100 / len; |
stema | 0:cd3dd72a93f5 | 88 | if (percent_done != percent_done_new) { |
stema | 0:cd3dd72a93f5 | 89 | percent_done = percent_done_new; |
stema | 0:cd3dd72a93f5 | 90 | printf("Flashed %3ld%%\r", percent_done); |
stema | 0:cd3dd72a93f5 | 91 | } |
stema | 0:cd3dd72a93f5 | 92 | } |
stema | 0:cd3dd72a93f5 | 93 | } |
stema | 0:cd3dd72a93f5 | 94 | printf("Flashed 100%%\r\n"); |
stema | 0:cd3dd72a93f5 | 95 | |
stema | 0:cd3dd72a93f5 | 96 | delete[] page_buffer; |
stema | 0:cd3dd72a93f5 | 97 | |
stema | 0:cd3dd72a93f5 | 98 | flash.deinit(); |
stema | 0:cd3dd72a93f5 | 99 | } |
stema | 0:cd3dd72a93f5 | 100 |