STM32 擦除内部 FLASH 时间过长导
IWDG 复位
1 前言
客户反馈在使用 STM32F412 的时候,擦除 sector 8~11 发现时间过长,从而导致意外触发
IWDG 复位。
2 问题分析
2.1 问题详
通过与客户邮件和电话沟通,了解到客户主要是想使用内部 FLASH 暂时保存 IAP 升级时的程
序数据,在 IAP 升级的过程中,需要首先擦除内 FLASH 中一块足够大的空间,然后再写入升级数据。
客户的工程中有使用到 IWDG喂狗间隔大约 1.5S,客户的通过 SysTick 的方式计算出擦除 Sector8
大约需要 2ms,因此认为若一次擦除 sector8~11 大约需要 8ms,于是在代码中一次性擦除 sector8~11
后最后再来喂狗,但是,这样会触 IWDG 复位,这个与预期不一致,固此产生疑问。
2.2 问题
使用 NUCLEO-F412ZG 板尝试重现客户问题,主要代码如下:
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t beginTick =0,endTick =0;
uint32_t curSysTick=0,endSysTick =0;
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_IWDG_Init();
/* USER CODE BEGIN 2 */
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) //如果是看门狗复
{
/* Clear reset flags */
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
__HAL_RCC_CLEAR_RESET_FLAGS();
Error_Handler();
}
HAL_FLASH_Unlock();
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Sector = FLASH_SECTOR_8;
EraseInitStruct.NbSectors = 1;
// if(HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
// {
// Error_Handler();
// }
beginTick =HAL_GetTick();
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
curSysTick =SysTick->VAL;
if(HAL_FLASHEx_Erase_IT(&EraseInitStruct)!= HAL_OK) //擦除 sector8
{
Error_Handler();
}
endSysTick =SysTick->VAL; // curSysTick, endSysTick 保存着 SysTick 寄存器的值
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET); //PC8 波形表示擦除 FLASH 的时间间隔
endTick =HAL_GetTick(); // beginTick, endTick 保存着全局变量 Tick 的值
g_TickCount =endTick -beginTick; //变量 Tick 的时间差
HAL_IWDG_Refresh(&hiwdg);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK)
{
/* Refresh Error */
Error_Handler();
}
HAL_Delay(10);
}
/* USER CODE END 3 */
}
此外,同时在每个 SysTick 中断输出一个波形,用来检测 SysTick 是否正常