01问题描述
客户使用STM32H573用于他们的产品,主要是要用到STiROT功能。但客户反馈,在APP中有用到看门狗,不开STiROT的时候,一切正常。但是,一旦开启STiROT时,则会导致看门狗复位。 02问题分析
为了重现问题,在STM32H573-DK板上通过STM32CubeMx生成一个STiROT工程,其main函数如下所示: - int main(void){
- /* USER CODE BEGIN 1 */uint8_t Timer = 0;uint32_t ResetCnt = 0;/* USER CODE END 1 */
- /* MCU Configuration--------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();
- __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
- /* Configure The Vector Table address */SCB->VTOR = 0xC000400;/* !!! To boot in a secure way, ST_IROT has configured and activated the Memory Protection UnitIn order to keep a secure environment execution, you should reconfigure the MPU to make it compatible with your applicationIn this example, MPU is disabled */HAL_MPU_Disable();HAL_MPU_Disable_NS();
- /* USER CODE BEGIN Init */HAL_ICACHE_Disable();/* USER CODE END Init */
- /* Configure the system clock */SystemClock_Config();/* GTZC initialisation */MX_GTZC_S_Init();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();
- //打印看门狗相关寄存器内容printf("IWDG1-PR:0x%x,RLR:0x%x,WINR:0x%x,SR:0x%x\r\n",hiwdg.Instance->PR,hiwdg.Instance->RLR,hiwdg.Instance->WINR,hiwdg.Instance->SR);MX_IWDG_Init();/* USER CODE BEGIN 2 */
- HAL_IWDG_Refresh(&hiwdg); //喂狗//再次打印看门狗相关寄存器内容printf("IWDG2-PR:0x%x,RLR:0x%x,WINR:0x%x,SR:0x%x\r\n",hiwdg.Instance->PR,hiwdg.Instance->RLR,hiwdg.Instance->WINR,hiwdg.Instance->SR);HAL_IWDG_Refresh(&hiwdg); //再次喂狗if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != 0x00u){printf("IWDG reset.\r\n");}__HAL_RCC_CLEAR_RESET_FLAGS();HAL_IWDG_Refresh(&hiwdg);printf("Clear reset flag.\r\n");HAL_IWDG_Refresh(&hiwdg);/* USER CODE END 2 */
- /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */HAL_IWDG_Refresh(&hiwdg);HAL_Delay(500);HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
- HAL_IWDG_Refresh(&hiwdg);HAL_Delay(500);HAL_GPIO_TogglePin(LED_ORANGE_GPIO_Port, LED_ORANGE_Pin);
- HAL_IWDG_Refresh(&hiwdg);HAL_Delay(500);HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
- HAL_IWDG_Refresh(&hiwdg);HAL_Delay(500);HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);}/* USER CODE END 3 */}
如上代码,在不开启STiROT时一切运行正常。而在开启STiROT,按照STiRoT的要求Provisioning后,其打印如下所示:
从打印信息可知已经重现了问题现象,MCU一直在复位。 分析此打印信息,我们可得到如下信息: 1. 第二次打印看门狗寄存器的过程中触发了看门狗复位。这确认了看门狗复位事件发生在运行用户代码时,而不是运行STiROT期间。 2. 但是在第二次打印看门狗寄存器内容之前,刚刚执行了喂狗动作,看起来此时喂狗动作并没有生效。 3. 作为对比,相同的代码,在不开启STiROT时则一切正常。这说明此问题确实与STiROT相关。 4. 另外,对于时间参数。我有修改过,即使时间参数进行延时,结果还是会有看门狗复位现象。此问题看起来跟时间参数并无多大关系。 整个现象给人的感觉就是喂狗函数HAL_IWDG_Refresh()异常,此函数似乎并没生效。 通过和内部产品部门的专家沟通,发现STiROT对看门狗实施了写保护的嫌疑最大。为了确认怀疑,在代码中对看门狗初始化之前,先执行一次关闭写保护: - hiwdg.Instance = IWDG;__HAL_IWDG_START(&hiwdg);IWDG_ENABLE_WRITE_ACCESS(&hiwdg); //允许写HAL_Delay(1); //在这里需要加点延时MX_IWDG_Init(); //再初始化看门狗…
如此修改后,则一切又恢复正常了。
问题解决! 03后述
虽然在MX_IWDG_Init()函数内部也会做使能写的动作,但是经过测试,如果不额外添加代码,并不能工作。不排除将来HAL库更新版本后会解决此问题,不过在此之前,则可将此文档所描述的方法作为一种参考。
|