2024-12-12 09:44 PM - last edited on 2024-12-13 12:19 AM by Andrew Neil
Hi All, trying to write data into flash with dynamical flash address selection approach but it fails but at same time if hash(#) define the address the flash programming all works fine, Please suggest me the best solution and explain me the issues choosing dynamical address for flash address.
typedef struct {
uint32_t active_app; // 1 for App1, 2 for App2
uint32_t app1_valid; // 1 if App1 is valid
uint32_t app2_valid; // 1 if App2 is valid
} BootInfo;
#define BOOT_INFO_ADDRESS 0x0802F000
int8_t UpdateFWBlueNRG(uint32_t *SizeOfUpdate,uint8_t * att_data, int32_t data_length)
{
int8_t ReturnValue=0;
/* Save the Packed received */
if(data_length>(*SizeOfUpdate)){
/* Too many bytes...Something wrong... necessity to send it again... */
// OTA_PRINTF("OTA something wrong data_length=%ld RemSizeOfUpdate=%ld....\r\nPlease Try again\r\n", (long)data_length, (long)(*SizeOfUpdate));
ReturnValue = -1;
/* Reset for Restarting again */
*SizeOfUpdate=0;
} else {
uint64_t ValueToWrite;
int32_t Counter;
// Clear all flash error flags
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR );
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_FWWERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_NOTZEROERR);
BootInfo* boot_info = (BootInfo*)BOOT_INFO_ADDRESS;
uint32_t target_address = (boot_info->active_app == 1) ? 0x0801C000 : 0x08005000;
/* Save the received OTA packed ad save it to flash */
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
for(Counter=0;Counter<data_length;Counter+=8){
memcpy((uint8_t*) &ValueToWrite,att_data+Counter,8);
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLE, target_address,ValueToWrite)==HAL_OK){
target_address+=8;
} else {
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error
FLASH_ErrorTypeDef errorcode = HAL_FLASH_GetError(); */
while(1){
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay (1000);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay (1000);}
OTA_ERROR_FUNCTION();
}
}
/* Reduce the remaining bytes for OTA completion */
*SizeOfUpdate -= data_length;
if(*SizeOfUpdate==0) {
/* We had received the whole firmware and we have saved it in Flash */
OTA_PRINTF("OTA Update saved\r\n");
NVIC_SystemReset();
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
}
return ReturnValue;
}
*////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Now this code works fine if instead of choosing address dynamically and putting # define Writing_address 0x0801C000
#define Writting_addresss 0x0801C000
int8_t UpdateFWBlueNRG(uint32_t *SizeOfUpdate,uint8_t * att_data, int32_t data_length)
{
int8_t ReturnValue=0;
/* Save the Packed received */
if (data_length>(*SizeOfUpdate)) {
/* Too many bytes...Something wrong... necessity to send it again... */
// OTA_PRINTF("OTA something wrong data_length=%ld RemSizeOfUpdate=%ld....\r\nPlease Try again\r\n", (long)data_length, (long)(*SizeOfUpdate));
ReturnValue = -1;
/* Reset for Restarting again */
*SizeOfUpdate=0;
}
else {
uint64_t ValueToWrite;
int32_t Counter;
// Clear all flash error flags
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR );
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_FWWERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_NOTZEROERR);
/* Save the received OTA packed ad save it to flash */
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
for(Counter=0;Counter<data_length;Counter+=8){
memcpy((uint8_t*) &ValueToWrite,att_data+Counter,8);
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLE,Writting_addresss,ValueToWrite)==HAL_OK){
Writting_addresss+=8;
} else {
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error
FLASH_ErrorTypeDef errorcode = HAL_FLASH_GetError(); */
while(1){
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay (1000);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay (1000);}
OTA_ERROR_FUNCTION();
}
}
/* Reduce the remaining bytes for OTA completion */
*SizeOfUpdate -= data_length;
if(*SizeOfUpdate==0) {
/* We had received the whole firmware and we have saved it in Flash */
OTA_PRINTF("OTA Update saved\r\n");
NVIC_SystemReset();
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
}
return ReturnValue;
}
Solved! Go to Solution.
2024-12-13 12:09 AM
Hello,
Declare target_address volatile:
__IO uint32_t target_address
2024-12-12 11:42 PM
I edited you post to use the proper code tags; please see How to insert source code for future reference.
See also How to write your question to maximize your chances to find a solution
@satyam9896 wrote:trying to write data into flash with dynamical flash address selection approach but it fails
So how, exactly, does it "fail" ?
2024-12-13 12:09 AM
Hello,
Declare target_address volatile:
__IO uint32_t target_address
2024-12-19 12:08 AM - edited 2024-12-19 02:31 AM
As your issue has been solved according to this thread, please close this one by marking the comment that guided you to the solution Accepted as Solution.
2024-12-19 12:05 PM - edited 2024-12-19 09:06 PM
Hi I have put above reply for flash write it as an solution accepted but please help me out in while erasing the flash fn. the point it will not erase the selected reason but if do hard code Nb.pages (256) instead for getting it from Getpage first and last.
the pages of this stm32l072 198kb are 128bytes each page and 4kb per sector.
uint32_t GetPage(uint32_t Addr)
{
uint32_t page = 0;
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
/* Bank 1 */
page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}
else
{
/* Bank 2 */
page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
}
return page;
}
void StartUpdateFWBlueNRG(uint32_t SizeOfUpdate, uint32_t uwCRCValue)
{
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR );
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_FWWERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_NOTZEROERR);
// BootInfo* boot_info = (BootInfo*)BOOT_INFO_ADDRESS;
// uint32_t target_address = (boot_info->active_app == 1) ? 0x0801C000 : 0x08005000;
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t SectorError = 0;
OTA_PRINTF("Start FLASH Erase\r\n");
SizeOfUpdateBlueFW = SizeOfUpdate;
AspecteduwCRCValue = uwCRCValue;
WritingAddress = OTA_ADDRESS_START;
// WritingAddress = target_address;
// Compute first and last pages
uint32_t FirstPage = GetPage(0x0801C000);
// uint32_t LastAddress = WritingAddress + SizeOfUpdate - 1;
uint32_t LastPage = GetPage(0x0802300-1);
uint32_t NbPages = LastPage - FirstPage + 1;
// Compute number of pages to erase
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = 0x0801C000;
EraseInitStruct.NbPages = 256/*((LastPage - FirstPage) / FLASH_PAGE_SIZE) + 1*/;
// Unlock the Flash
HAL_FLASH_Unlock();
// Clear all flash error flags
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR );
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_FWWERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_NOTZEROERR);
// __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGFLASH_FLAG_EOPAERR);
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
uint16_t errorcode = HAL_FLASH_GetError();
OTA_PRINTF("Flash Erase Error: 0x%08lX\r\n", (long)errorcode);
OTA_ERROR_FUNCTION();
} else {
OTA_PRINTF("End FLASH Erase %ld Pages of %d Bytes\r\n", (long)EraseInitStruct.NbPages, FLASH_PAGE_SIZE);
}
// Lock the Flash
HAL_FLASH_Lock();
}