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 是否正常:
- <font face="Tahoma"><font size="3"><font color="#000000">void HAL_SYSTICK_Callback(void)</font></font></font>
- <font face="Tahoma"><font size="3"><font color="#000000">{</font></font></font>
- <font face="Tahoma"><font size="3"><font color="#000000">HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_11);//用 PA11 来检测 SysTick 波形</font></font></font>
- <font face="Tahoma"><font size="3"><font color="#000000">}</font></font></font>
复制代码
最终得出的波形如下:
如上图,黄色为 PC8 脚波形,表示擦除 FLASH 的时间,下面蓝色为 PA11 管脚波形,表示 SysTick 波形。
完整版请查看:附件
|