Reputation: 373
When I try and erase the flash memory on my STM32L451 using HAL, the erase operation fails and the when I get the flash error it returns HAL_FLASH_ERROR_PGS. This is a programming sequence error.
I'm trying to erase the last page in my flash memory that is used for configuration data. This sector has been defined as separate section in the linker.
The code will try and erase one page at address 0x0807F800 (page 255)
Here is my calling code:
PT_SPAWN(Thread_PS, &LocalThread_S, INT_MEMORY_Erase_V(&LocalThread_S, 0x0807F800, 80, &Result_B));
And here is my flash erase function:
PT_THREAD(INT_MEMORY_Erase_V(struct pt *Thread_PS, uint32_t Offset_U32, uint32_t Length_U32, bool *Result_PB))
{
FLASH_EraseInitTypeDef EraseInitStruct_S;
uint32_t PageError_U32;
static uint32_t LocalOffset_U32;
static uint32_t PageCount_U32;
PT_BEGIN(Thread_PS);
// Initialise the variables
*Result_PB = false;
LocalOffset_U32 = Offset_U32 & ~(FLASH_PAGE_SIZE - 1);
PageCount_U32 = Length_U32 / FLASH_PAGE_SIZE;
if ((Length_U32 - (PageCount_U32 * FLASH_PAGE_SIZE)) != 0)
{
PageCount_U32 ++;
}
PT_WAIT_UNTIL(Thread_PS, HAL_FLASH_Unlock() == HAL_OK);
PT_WAIT_UNTIL(Thread_PS, HAL_FLASH_OB_Unlock() == HAL_OK);
EraseInitStruct_S.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct_S.Page = (LocalOffset_U32 - FLASH_BASE) / FLASH_PAGE_SIZE;
EraseInitStruct_S.Banks = FLASH_BANK_1;
EraseInitStruct_S.NbPages = PageCount_U32;
// Clear all the error flags
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
// If we could erase the flash
if (HAL_FLASHEx_Erase(&EraseInitStruct_S, &PageError_U32) == HAL_OK)
{
*Result_PB = true;
}
else
{
int_memory_Error_U32 = HAL_FLASH_GetError();
}
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
PT_END(Thread_PS);
}
I've tried several things but cannot resolve the problem. It is odd because the same code works perfectly fine in my bootloader.
Upvotes: 1
Views: 1892
Reputation: 373
It has been a while since I posted this question but only managed to look at it now.
There was two reasons for not being able to erase and write the internal flash from my application.
The erase operation failed due to a timer (TIM16). When I enabled the timer and its interrupt, I could not erase the flash. I did not have the time to look at what exactly is causing this, but resolved it by using another timer (TIM2).
Once the erase was working, I could not write.
This was due to the data being casted to a 64 bit pointer for writing to the internal flash but the data was not aligned for 64 bit access. The original data was in a packed structure. I resolved this by first copying the data to a 64 bit array before writing it to the internal flash. I guess it could be possible to align the packed structure.
Something I learned from this is that the STM32 CubIDE has a built in fault analyzer which is very helpful when trying to resolve fault exceptions like a hardware fault exception.
The fault analyzer can be found in debug mode under Window->Show View->Fault Analyzer.
Upvotes: 0