Simple F411 bootloader.

Dependencies:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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