stm32f4-uart-bootloader

Simple UART bootloader for STM32F4 MCU's
git clone git://git.mdnr.space/stm32f4-uart-bootloader
Log | Files | Refs | Submodules | README | LICENSE

flash-io.c (3943B)


      1 #include "flash-io.h"
      2 #include <stdint.h>
      3 #include <string.h>
      4 #include <stdbool.h>
      5 #include "shared/parameters.h"
      6 #include "shared/fwinfo.h"
      7 #include "shared/mem-blocks.h"
      8 
      9 static uint32_t mainAppEntry = 0XFFFF;
     10 
     11 uint8_t flash_io_read_params(uint8_t *buffer, uint8_t offset, uint8_t length){
     12     if ((offset + length) > (sizeof(Parameters_t))) {
     13         return 0;
     14     }
     15     memcpy(buffer, (uint8_t *)(MEM_PARAMS_OFFSET + offset), length);
     16     // TODO: handle errors here
     17     return length;
     18 }
     19 
     20 uint8_t flash_io_write_params(uint8_t *buffer, uint8_t offset, uint8_t length){
     21     if (length == 0 || offset != 0) {
     22         return 0;
     23     }         
     24     if ((offset + length) > (sizeof(Parameters_t))) {
     25         // TODO: send address out of range message
     26         return 0;
     27     } 
     28     flash_unlock();
     29     flash_erase_sector(MEM_PARAMS_SECTOR, 3);
     30     for (uint16_t i = 0; i < length; i++) {
     31         flash_program_byte(MEM_PARAMS_OFFSET + i, buffer[i]);
     32     }
     33     flash_lock();
     34     // TODO: handle errors here
     35     return length;
     36 }
     37 
     38 uint8_t flash_io_read_fw_info(uint8_t *buffer, uint8_t offset, uint8_t length){
     39     if ((offset + length) > (sizeof(FirmwareInfo_t))) {
     40         // TODO: send address out of range message
     41         return 0;
     42     } 
     43     memcpy(buffer, (uint8_t *)(MEM_FW_INFO_OFFSET + offset), length);
     44     return length;
     45 }
     46 
     47 uint8_t flash_io_read_diagnostic(uint8_t *buffer) {
     48     uint32_t *diagAddr = (uint32_t *)MEM_DOGGY_LITTER_BOX_OFFSET;
     49     uint16_t diagCount = 0;
     50     while ((uint16_t) * (diagAddr + diagCount) != 0xFFFF) {
     51         diagCount++;
     52     }
     53     memcpy(buffer, (uint8_t *)(MEM_DOGGY_LITTER_BOX_OFFSET), diagCount);
     54     return diagCount;
     55 }
     56 
     57 void flash_io_dump_diagnostic(uint16_t diagReg) {
     58     uint16_t *dumpAddr = (uint16_t *)MEM_DOGGY_LITTER_BOX_OFFSET;
     59     static bool registerDumped = false;
     60     // Search for empty untouched memory
     61     while (!registerDumped) {
     62         if (*dumpAddr == 0xFFFF) {
     63             flash_unlock();
     64             flash_program_half_word((uint32_t)dumpAddr, diagReg);
     65             flash_lock();
     66             registerDumped = true;
     67             while(true);
     68         }
     69         dumpAddr++;
     70         if (((uint32_t)dumpAddr - MEM_DOGGY_LITTER_BOX_OFFSET) >=
     71                 MEM_DOGGY_LITTER_BOX_SIZE) {
     72             // Memory area is full. Reboot without dumping
     73             break;
     74         }
     75     }
     76 }
     77 
     78 bool flash_io_check_dev_id(uint32_t *id) {
     79     FirmwareInfo_t *fwInfo = (FirmwareInfo_t *)MEM_FW_INFO_OFFSET;
     80     uint32_t devID = fwInfo->deviceID;
     81     return *id == devID;
     82 }
     83 
     84 uint32_t flash_io_check_update_size(uint32_t *size) {
     85     if (*size > MEM_FW_CAPACITY) {
     86         return 0;
     87     }
     88     return *size;
     89 }
     90 
     91 bool flash_io_erase_fw_partition(void) {
     92     flash_unlock();
     93     for (uint8_t i = 0; i + MEM_PARAMS_SECTOR < 12; i++) {
     94         flash_erase_sector(MEM_PARAMS_SECTOR + i, 3);
     95     }
     96     // TODO: Check if the flash area is erased completely
     97     flash_lock();
     98     return true;
     99 }
    100 
    101 uint32_t flash_io_write_new_firmware(uint8_t *chunk, uint16_t len) {
    102     static uint32_t writtenBytesNo = 0;
    103     if (writtenBytesNo == MEM_PARAMS_SIZE) {
    104         // Hold on to first 4-bytes of vector table to flash it after everything else
    105         mainAppEntry = *(uint32_t *)chunk;
    106         *(uint32_t *)chunk = 0xFFFFFFFF; // Replace entry with all 1s
    107     }
    108     flash_unlock();
    109     for (uint8_t writeOffset = 0; writeOffset < len; writeOffset++) {
    110         flash_program_byte(MEM_PARAMS_OFFSET + (writeOffset + writtenBytesNo), chunk[writeOffset]);
    111     }
    112     flash_lock();
    113     writtenBytesNo += len;
    114     return len;
    115 }
    116 
    117 bool flash_io_check_fw_integrity(void) {
    118     uint32_t vecTableEntry = *(uint32_t *)MEM_APP_OFFSET;
    119     return !(vecTableEntry == 0xFFFFFFFF || vecTableEntry == 0x0); // Vector table is not written
    120 }
    121 
    122 // Write the vector table entry to flash memory
    123 bool flash_io_write_main_entry(void) {
    124     flash_unlock();
    125     flash_program_word(MEM_APP_OFFSET, mainAppEntry);
    126     flash_lock();
    127     return true;
    128 }