Imprecise error flag after writing to the flash
Hi experts,
I'm adding to my existing code (that runs on a STM32F105) a function to store a word in the flash.
I basically copied the code from the official example based on the HAL libraries, here my function:
uint32_t FLASH_Write_Data(uint32_t StartPageAddress, uint32_t *Data, uint16_t NWords)
{
static FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError;
/* Unlock the Flash memory to enable the flash control register access */
HAL_FLASH_Unlock();
/* Erase the FLASH area*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;
EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
{
/*Error occurred while page erase.*/
return HAL_FLASH_GetError();
}
/* Program the user FLASH area word by word*/
uint32_t i = 0;
while (i < NWords)
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, StartPageAddress, Data[i]) == HAL_OK)
{
StartPageAddress += MEMORY_OFFSET;
i++;
}
else
{
/* Error occurred while writing data in Flash memory*/
return HAL_FLASH_GetError();
}
}
HAL_FLASH_Lock();
return HAL_OK;
}The very first strange thing is that as soon as I start debugging, the program counter often jumps to the HardFault_Handler function.
From there, I can reset the chip and restart the debug session without any apparent problem.
However, when I execute the program, it consistently ends up in the HardFault_Handler function.
If I comment out the flash write function, the program works as expected.
I started commenting out part of the flash function code, and I noticed that when the HAL_FLASHEx_Erase and the HAL_FLASH_Program functions are not executed, the program continues to work as expected.
I stepped through the code and I didn't notice anything obviousy wrong, as I can erase and even write the passed value to the passed memory address without any immediate error!
The only thing that happens before the program counter jumps into the HardFault_Handler function is that, after several instructions, the IMPRECISERR flag of the CFS register is set.
I tried moving the flash function into the main code, just after the SystemClock_Config or just after before the while(1), but surprisingly, the instruction where the IMPRECISERR flag is set does not change.
The point where this is happening is on the closing (yes on the close function parenthesis "}") of this function:
bool Shaft_Measure(void)
{
static int32_t aShaft_old;
int32_t aShaft;
msg.a_shaft = (int16_t)aShaft;
if (ABS(aShaft - aShaft_old) > 1){
bRead_speed = true;
}
else{
bRead_speed = false;
}
aShaft_old = aShaft;
return bRead_speed;
}I'm sure that the problem is not there, but unfortunately I don't know how to proceed to identify the issue.
The MCU I'm using is the STM32F105RC which has 256 kB of flash, and the value I'm trying to save it is just a uint32_t number.
The constants used by the flash functions are defined in my flash.h here reported:
#define FLASH_ADDR_PAGE_127 ((uint32_t)0x0803F800)
#define FLASH_USER_START_ADDR FLASH_ADDR_PAGE_127
#define FLASH_USER_END_ADDR FLASH_ADDR_PAGE_127 + FLASH_PAGE_SIZE
#define MEMORY_OFFSET ((uint32_t)0x4U)These addresses have been copied from the device datasheet.
Here my system:
Segger JLink base (with the latest ver: 7.96l)
STM32CubeIDE (ver: 1.15.1)
STM32CubeMX (ver: 6.11.1)
HAL libraries for STM32F1 (ver: 1.8.5)
Any help would be greatly appreciated!
