From 0cc1907448220faf7a418556a9e65787f2c62c02 Mon Sep 17 00:00:00 2001 From: Satish Nair Date: Thu, 20 Mar 2014 19:11:21 +0530 Subject: [PATCH 1/2] Improved FLASH_Update() method - make OTA Update more reliable --- SPARK_Firmware_Driver/inc/hw_config.h | 2 +- SPARK_Firmware_Driver/src/hw_config.c | 46 ++++++++------------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/SPARK_Firmware_Driver/inc/hw_config.h b/SPARK_Firmware_Driver/inc/hw_config.h index 042ad60..2466987 100644 --- a/SPARK_Firmware_Driver/inc/hw_config.h +++ b/SPARK_Firmware_Driver/inc/hw_config.h @@ -236,7 +236,7 @@ void FLASH_Backup(uint32_t sFLASH_Address); void FLASH_Restore(uint32_t sFLASH_Address); /* External Flash Helper routines */ void FLASH_Begin(uint32_t sFLASH_Address); -void FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize); +bool FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize); void FLASH_End(void); void FLASH_Read_ServerAddress(ServerAddress *server_addr); void FLASH_Read_ServerPublicKey(uint8_t *keyBuffer); diff --git a/SPARK_Firmware_Driver/src/hw_config.c b/SPARK_Firmware_Driver/src/hw_config.c index 99693f6..aaa97b1 100644 --- a/SPARK_Firmware_Driver/src/hw_config.c +++ b/SPARK_Firmware_Driver/src/hw_config.c @@ -1484,49 +1484,31 @@ void FLASH_Begin(uint32_t sFLASH_Address) #endif } -void FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize) +bool FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize) { #ifdef SPARK_SFLASH_ENABLE - uint32_t i = bufferSize >> 2; + uint8_t *writeBuffer = pBuffer; + uint8_t readBuffer[bufferSize]; + bool Flash_Updated = false; - /* Program External Flash */ - while (i--) - { - Internal_Flash_Data = *((uint32_t *)pBuffer); - pBuffer += 4; - - /* Program Word to SPI Flash memory */ - External_Flash_Data[0] = (uint8_t)(Internal_Flash_Data & 0xFF); - External_Flash_Data[1] = (uint8_t)((Internal_Flash_Data & 0xFF00) >> 8); - External_Flash_Data[2] = (uint8_t)((Internal_Flash_Data & 0xFF0000) >> 16); - External_Flash_Data[3] = (uint8_t)((Internal_Flash_Data & 0xFF000000) >> 24); - //OR - //*((uint32_t *)External_Flash_Data) = Internal_Flash_Data; - sFLASH_WriteBuffer(External_Flash_Data, External_Flash_Address, 4); - External_Flash_Address += 4; - } + /* Write Data Buffer to SPI Flash memory */ + sFLASH_WriteBuffer(writeBuffer, External_Flash_Address, bufferSize); - i = bufferSize & 3; + /* Read Data Buffer from SPI Flash memory */ + sFLASH_ReadBuffer(readBuffer, External_Flash_Address, bufferSize); - /* Not an aligned data */ - if (i != 0) + /* Is the Data Buffer successfully programmed to SPI Flash memory */ + if(0 == memcmp(writeBuffer, readBuffer, bufferSize)) { - /* Program the last word to SPI Flash memory */ - Internal_Flash_Data = *((uint32_t *)pBuffer); - - /* Program Word to SPI Flash memory */ - External_Flash_Data[0] = (uint8_t)(Internal_Flash_Data & 0xFF); - External_Flash_Data[1] = (uint8_t)((Internal_Flash_Data & 0xFF00) >> 8); - External_Flash_Data[2] = (uint8_t)((Internal_Flash_Data & 0xFF0000) >> 16); - External_Flash_Data[3] = (uint8_t)((Internal_Flash_Data & 0xFF000000) >> 24); - //OR - //*((uint32_t *)External_Flash_Data) = Internal_Flash_Data; - sFLASH_WriteBuffer(External_Flash_Data, External_Flash_Address, 4); + External_Flash_Address += bufferSize; + Flash_Updated = true; } LED_Toggle(LED_RGB); + return Flash_Updated; + #endif } From e1111316189b15910b431b9dbdfb24629e45fff4 Mon Sep 17 00:00:00 2001 From: Satish Nair Date: Fri, 21 Mar 2014 21:37:39 +0530 Subject: [PATCH 2/2] FLASH_Update-Erase Flash pages for failure and return next_chunk_index --- SPARK_Firmware_Driver/inc/hw_config.h | 2 +- SPARK_Firmware_Driver/src/hw_config.c | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/SPARK_Firmware_Driver/inc/hw_config.h b/SPARK_Firmware_Driver/inc/hw_config.h index 2466987..f5a23ca 100644 --- a/SPARK_Firmware_Driver/inc/hw_config.h +++ b/SPARK_Firmware_Driver/inc/hw_config.h @@ -236,7 +236,7 @@ void FLASH_Backup(uint32_t sFLASH_Address); void FLASH_Restore(uint32_t sFLASH_Address); /* External Flash Helper routines */ void FLASH_Begin(uint32_t sFLASH_Address); -bool FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize); +uint16_t FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize); void FLASH_End(void); void FLASH_Read_ServerAddress(ServerAddress *server_addr); void FLASH_Read_ServerPublicKey(uint8_t *keyBuffer); diff --git a/SPARK_Firmware_Driver/src/hw_config.c b/SPARK_Firmware_Driver/src/hw_config.c index aaa97b1..9f2cfef 100644 --- a/SPARK_Firmware_Driver/src/hw_config.c +++ b/SPARK_Firmware_Driver/src/hw_config.c @@ -91,6 +91,7 @@ uint32_t Internal_Flash_Address = 0; uint32_t External_Flash_Address = 0; uint32_t Internal_Flash_Data = 0; uint8_t External_Flash_Data[4]; +uint16_t Flash_Update_Index = 0; uint32_t EraseCounter = 0; uint32_t NbrOfPage = 0; volatile FLASH_Status FLASHStatus = FLASH_COMPLETE; @@ -1470,6 +1471,7 @@ void FLASH_Begin(uint32_t sFLASH_Address) Save_SystemFlags(); //BKP_WriteBackupRegister(BKP_DR10, 0x5555); + Flash_Update_Index = 0; External_Flash_Address = sFLASH_Address; /* Define the number of External Flash pages to be erased */ @@ -1484,13 +1486,12 @@ void FLASH_Begin(uint32_t sFLASH_Address) #endif } -bool FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize) +uint16_t FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize) { #ifdef SPARK_SFLASH_ENABLE uint8_t *writeBuffer = pBuffer; uint8_t readBuffer[bufferSize]; - bool Flash_Updated = false; /* Write Data Buffer to SPI Flash memory */ sFLASH_WriteBuffer(writeBuffer, External_Flash_Address, bufferSize); @@ -1499,15 +1500,22 @@ bool FLASH_Update(uint8_t *pBuffer, uint32_t bufferSize) sFLASH_ReadBuffer(readBuffer, External_Flash_Address, bufferSize); /* Is the Data Buffer successfully programmed to SPI Flash memory */ - if(0 == memcmp(writeBuffer, readBuffer, bufferSize)) + if (0 == memcmp(writeBuffer, readBuffer, bufferSize)) { External_Flash_Address += bufferSize; - Flash_Updated = true; + Flash_Update_Index += 1; + } + else + { + /* Erase the problematic SPI Flash pages and back off the chunk index */ + External_Flash_Address = ((uint32_t)(External_Flash_Address / sFLASH_PAGESIZE)) * sFLASH_PAGESIZE; + sFLASH_EraseSector(External_Flash_Address); + Flash_Update_Index = (uint16_t)((External_Flash_Address - EXTERNAL_FLASH_OTA_ADDRESS) / bufferSize); } LED_Toggle(LED_RGB); - return Flash_Updated; + return Flash_Update_Index; #endif }