Explorar el Código

Refactor flash programmer

Removed as much custom code from the ZuluSCSI_bootloader.cpp for the
F4 into ZuluSCSI_platform.cpp. In ZuluSCSI_platform.cpp, created
a generic sector eraser (erase_flash_sector) and a generic flash
writer (write_flash) that can be reused for something else.

Because there are now two ways to erase the flash in the
ZuluSCSI_bootloader.cpp (page and sector) for all the environments,
it might be worth refactoring out that specific detail for each
environment.
Morio hace 2 años
padre
commit
a66c3beafc

+ 158 - 17
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_platform.cpp

@@ -576,7 +576,7 @@ static uint32_t sector_number_to_id(uint32_t sector_number)
     return SECTOR_NUMBER_TO_ID_ERROR;
 }
 
-bool platform_erase_flash_sector(uint32_t sector)
+static bool erase_flash_sector(uint32_t sector)
 {
     fmc_unlock();
     fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
@@ -597,27 +597,14 @@ bool platform_erase_flash_sector(uint32_t sector)
     return true;
 }
 
-bool platform_write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATFORM_FLASH_WRITE_BUFFER_SIZE])
+static bool write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATFORM_FLASH_WRITE_BUFFER_SIZE])
 {
-    if (offset == 0)
-    {
-        if (buffer[3] != 0x20 || buffer[7] != 0x08)
-        {
-            logmsg("Invalid firmware file, starts with: ", bytearray(buffer, 16));
-            return false;
-        }
-
-    }
-
-    dbgmsg("Writing flash at firmware offset ", offset, " data ", bytearray(buffer, 4));
-    assert(offset % PLATFORM_FLASH_WRITE_BUFFER_SIZE == 0);
-    //assert(offset >= PLATFORM_BOOTLOADER_SIZE);
         
     fmc_unlock();
     fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
     fmc_state_enum status;
     uint32_t *buf32 = (uint32_t*)buffer;
-    uint32_t memory_address = FLASH_BASE + PLATFORM_BOOTLOADER_SIZE + offset;
+    uint32_t memory_address = FLASH_BASE + offset;
     uint32_t num_words = length / 4;
     if (length % 4 == 0)
     {
@@ -638,7 +625,7 @@ bool platform_write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATF
     }
 
     fmc_lock();
-    memory_address = FLASH_BASE + PLATFORM_BOOTLOADER_SIZE + offset;
+    memory_address = FLASH_BASE + offset;
     for (int i = 0; i < num_words; i++)
     {
         uint32_t expected = buf32[i];
@@ -654,6 +641,160 @@ bool platform_write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATF
     return true;
 }
 
+// the size of the main code without the bootloader
+static uint32_t firmware_size(FsFile &file)
+{
+    uint32_t fwsize = file.size();
+    if (fwsize <=  PLATFORM_BOOTLOADER_SIZE )
+    {
+        logmsg("Firmware file size too small: ", fwsize, " bootloader fits in the first : ", PLATFORM_BOOTLOADER_SIZE, " bytes");
+        return false;
+    }
+    return fwsize - PLATFORM_BOOTLOADER_SIZE;
+}
+
+bool platform_firmware_erase(FsFile &file)
+{
+    uint32_t bootloader_sector_index = 0;
+    uint32_t bootloader_sector_byte_count = 0;
+    const uint32_t map_length = sizeof(platform_flash_sector_map)/sizeof(platform_flash_sector_map[0]);
+    // Find at which sector the bootloader ends so it isn't overwritten
+    for(;;)
+    {
+        if (bootloader_sector_index < map_length)
+        {
+            bootloader_sector_byte_count += platform_flash_sector_map[bootloader_sector_index];
+            if (bootloader_sector_byte_count < PLATFORM_BOOTLOADER_SIZE)
+            {
+                bootloader_sector_index++;
+            }
+            else
+            {
+                break;
+            }    
+        }
+        else
+        {
+            logmsg("Bootloader does not fit in flash");
+            return false;
+        }
+                
+    }
+    
+    // find the last sector the mainline firmware ends
+    uint32_t fwsize = firmware_size(file);
+    uint32_t firmware_sector_start = bootloader_sector_index + 1;
+    uint32_t last_sector_index = firmware_sector_start;
+    uint32_t last_sector_byte_count = 0;
+    for(;;)
+    {
+        if (last_sector_index < map_length)
+        {
+            last_sector_byte_count += platform_flash_sector_map[last_sector_index];
+            if (fwsize > last_sector_byte_count)
+            {
+                last_sector_index++;
+            }
+            else
+            {
+                break;
+            }
+        }
+        else
+        {
+            logmsg("Firmware too large: ", (int) fwsize, 
+                    " space left after the bootloader ",  last_sector_byte_count,
+                    " total flash size ", (int)PLATFORM_FLASH_TOTAL_SIZE);
+            return false;
+        }
+    }
+
+    // Erase the sectors the mainline firmware will be written to
+    for (int i = firmware_sector_start; i <= last_sector_index; i++)
+    {
+        if (i % 2 == 0)
+        {
+            LED_ON();
+        }
+        else
+        {
+            LED_OFF();
+        }
+
+        if (!erase_flash_sector(i))
+        {
+            logmsg("Flash failed to erase sector ", i);
+            return false;
+        }
+        
+    }
+    LED_OFF();
+    return true;
+}
+
+bool platform_firmware_program(FsFile &file)
+{
+    // write the mainline firmware to flash
+    int32_t bytes_read = 0;
+    uint32_t address_offset = PLATFORM_BOOTLOADER_SIZE;
+    
+    // Make sure the buffer is aligned to word boundary
+    static uint32_t buffer32[PLATFORM_FLASH_WRITE_BUFFER_SIZE / 4];
+    uint8_t *buffer = (uint8_t*)buffer32;
+
+    if (!file.seek(PLATFORM_BOOTLOADER_SIZE))
+    {
+        logmsg("Seek failed");
+        return false;
+    }
+
+    dbgmsg("Writing flash at firmware offset ", address_offset, " data ", bytearray(buffer, 4));
+
+    for(;;)
+    {
+        if ((address_offset - PLATFORM_BOOTLOADER_SIZE) / PLATFORM_FLASH_WRITE_BUFFER_SIZE % 2)
+        {
+            LED_ON();
+        }
+        else
+        {
+            LED_OFF();
+        }
+        
+        bytes_read = file.read(buffer, PLATFORM_FLASH_WRITE_BUFFER_SIZE);
+        if ( bytes_read < 0)
+        {
+            logmsg("Firmware file read failed, error code ", (int) bytes_read);
+            return false;
+        }
+        if (!write_flash(address_offset, bytes_read, buffer))
+        {
+            logmsg("Failed to write flash at offset: ", address_offset, " bytes read: ",(int) bytes_read);
+            return false;
+        }
+        
+        // check the mainline firmware is valid
+        if (address_offset == PLATFORM_BOOTLOADER_SIZE)
+        {
+            if (buffer[3] != 0x20 || buffer[7] != 0x08)
+            {
+                logmsg("Invalid firmware file, starts with: ", bytearray(buffer, 16));
+                return false;
+            }
+
+        }
+
+        if (bytes_read < PLATFORM_FLASH_WRITE_BUFFER_SIZE)
+        {
+            break;
+        }
+        address_offset += bytes_read;
+        
+    }
+    LED_OFF();
+    return true;
+}
+
 void platform_boot_to_main_firmware()
 {
     uint32_t *mainprogram_start = (uint32_t*)(0x08000000 + PLATFORM_BOOTLOADER_SIZE);

+ 6 - 2
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_platform.h

@@ -29,7 +29,10 @@
 #include <scsi2sd.h>
 #include "ZuluSCSI_config.h"
 
+
 #ifdef __cplusplus
+#include <SdFat.h>
+
 extern "C" {
 #endif
 
@@ -136,8 +139,7 @@ const uint32_t platform_flash_sector_map[] =
         128 * 1024, 
         128 * 1024
     };
-bool platform_erase_flash_sector(uint32_t sector);
-bool platform_write_flash(uint32_t sector_index, uint32_t offset, uint8_t buffer[PLATFORM_FLASH_WRITE_BUFFER_SIZE]);
+
 void platform_boot_to_main_firmware();
 
 // Configuration customizations based on DIP switch settings
@@ -181,6 +183,8 @@ extern const uint32_t g_scsi_out_byte_to_bop[256];
 #ifdef __cplusplus
 }
 
+bool platform_firmware_erase(FsFile &file);
+bool platform_firmware_program(FsFile &file);
 // SD card driver for SdFat
 
 // SDIO interface, ZuluSCSI v1.4

+ 4 - 111
src/ZuluSCSI_bootloader.cpp

@@ -24,8 +24,8 @@
 #include <ZuluSCSI_platform.h>
 #include "ZuluSCSI_config.h"
 #include "ZuluSCSI_log.h"
-#include <SdFat.h>
 #include <string.h>
+#include <SdFat.h>
 
 #ifdef PLATFORM_BOOTLOADER_SIZE
 
@@ -106,123 +106,16 @@ bool program_firmware(FsFile &file)
 #else // PLATFORM_FLASH_SECTOR_ERASE
 bool program_firmware(FsFile &file)
 {
-    uint32_t bootloader_sector_index = 0;
-    uint32_t bootloader_sector_byte_count = 0;
-    const uint32_t map_length = sizeof(platform_flash_sector_map)/sizeof(platform_flash_sector_map[0]);
-    // Find at which sector the bootloader ends so it isn't overwritten
-    for(;;)
-    {
-        if (bootloader_sector_index < map_length)
-        {
-            bootloader_sector_byte_count += platform_flash_sector_map[bootloader_sector_index];
-            if (bootloader_sector_byte_count < PLATFORM_BOOTLOADER_SIZE)
-            {
-                bootloader_sector_index++;
-            }
-            else
-            {
-                break;
-            }    
-        }
-        else
-        {
-            logmsg("Bootloader does not fit in flash");
-            return false;
-        }
-                
-    }
-
-    uint32_t fwsize = file.size();
-    if (fwsize <=  PLATFORM_BOOTLOADER_SIZE )
+    if (!platform_firmware_erase(file))
     {
-        logmsg("Firmware file size too small: ", fwsize, " bootloader fits in the first : ", PLATFORM_BOOTLOADER_SIZE, " bytes");
         return false;
     }
-    fwsize -= PLATFORM_BOOTLOADER_SIZE;
-    
-    // find the last sector the mainline firmware ends
-    uint32_t firmware_sector_start = bootloader_sector_index + 1;
-    uint32_t last_sector_index = firmware_sector_start;
-    uint32_t last_sector_byte_count = 0;
-    for(;;)
-    {
-        if (last_sector_index < map_length)
-        {
-            last_sector_byte_count += platform_flash_sector_map[last_sector_index];
-            if (fwsize > last_sector_byte_count)
-            {
-                last_sector_index++;
-            }
-            else
-            {
-                break;
-            }
-        }
-        else
-        {
-            logmsg("Firmware too large: ", (int) fwsize, 
-                    " space left after the bootloader ",  last_sector_byte_count,
-                    " total flash size ", (int)PLATFORM_FLASH_TOTAL_SIZE);
-            return false;
-        }
-    }
-
-    // Make sure the buffer is aligned to word boundary
-    static uint32_t buffer32[PLATFORM_FLASH_WRITE_BUFFER_SIZE / 4];
-    uint8_t *buffer = (uint8_t*)buffer32;
-
-    if (!file.seek(PLATFORM_BOOTLOADER_SIZE))
+    if (!platform_firmware_program(file))
     {
-        logmsg("Seek failed");
         return false;
     }
-
-    // Erase the sectors the mainline firmware will be written to
-    for (int i = firmware_sector_start; i <= last_sector_index; i++)
-    {
-        LED_ON();
-        if (!platform_erase_flash_sector(i))
-        {
-            logmsg("Flash failed to erase sector ", i);
-            return false;
-        }
-        LED_OFF();
-    }
-
-    // write the mainline firmware to flash
-    int32_t bytes_read = 0;
-    uint32_t address_offset = 0;
-    for(;;)
-    {
-        if (address_offset / PLATFORM_FLASH_WRITE_BUFFER_SIZE % 2)
-        {
-            LED_ON();
-        }
-        else
-        {
-            LED_OFF();
-        }
-        
-        bytes_read = file.read(buffer, PLATFORM_FLASH_WRITE_BUFFER_SIZE);
-        if ( bytes_read < 0)
-        {
-            logmsg("Firmware file read failed, error code ", (int) bytes_read);
-            return false;
-        }
-        if (!platform_write_flash(address_offset, bytes_read, buffer))
-        {
-            logmsg("Failed to write flash at offset: ", address_offset, " bytes read: ",(int) bytes_read);
-            return false;
-        }
-        if (bytes_read < PLATFORM_FLASH_WRITE_BUFFER_SIZE)
-        {
-            break;
-        }
-        address_offset += bytes_read;
-        
-    }
-    LED_OFF();
     return true;
+    
 }
 
 #endif // PLATFORM_FLASH_SECTOR_ERASE