I'm trying to erase all bootloader from flash (2 pages of 2 KB, starting from address 0x08000000) in STM32F302RBT6, and as my code app starts from the 0x08001000 address should not be a problem to do it. The point is, after the erasing function returns, a hard fault it's generated with a memory fault IACCVIOL and never reaches the while(1).
public int main (void)
{
HAL_Init();
ClockInit();
APP_MEM_EraseBootloaderSectorInFlash();
while(1);
}
unsigned char APP_MEM_EraseBootloaderSectorInFlash(void)
{
unsigned char result = 0;
__disable_irq();
HAL_FLASH_Unlock();
result = ErasePageinFlash(0x08000000);
result = ErasePageinFlash(0x08000800);
HAL_FLASH_Lock();
__enable_irq();
return result;
}
static unsigned char ErasePageinFlash(uint32_t page_address)
{
unsigned char result = 0;
uint32_t page_error;
FLASH_EraseInitTypeDef erase_init;
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
erase_init.NbPages = 1u;
erase_init.PageAddress = page_address;
if (HAL_FLASHEx_Erase(&erase_init, &page_error) == HAL_OK)
{
result = 1;
}
return result;
}
PS. I've Already tried some things:
If I erase two pages starting in 0x08003000 (not used by the application), it works fine, and no fault is generated.
If I debug the code step by step, the problem doesn't occur. The code reaches the while(1).
I've tried to reduce the clock and increment flash latency, but it didn't work.
If I change the position of the while(1) from the main function and put it inside the APP_MEM_EraseBootloaderSectorInFlash function, it works fine, and no fault is generated.
This is the code of ClockInit:
static void ClockInit(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
//RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
while (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
// TODO :: Fault behaviour
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
while (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
// TODO :: Fault behaviour
}
}