最近在将手头的两块STM32开发板移植FreeRTOS系统,之前用着都好好的。一块是STM32F103VCT6,一块是STM32VET6。
我用STM32cubeMx 4.27版本配置项目代码,生成后进行调试。程序居然没跑起来,作为一个玩了多年STM32的“老手”,启动调试模式。发现程序卡死在系统时钟配置函数内部:SystemClock_Config()。
这个函数的定义:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
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;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}
而系统单步运行进入了_Error_Handler(__FILE__, __LINE__),之后就再也跳不出来了。
而_Error_Handler(__FILE__, __LINE__)的定义如下:
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
我换用了STM32CubeMX 5.3版本,同样的操作步骤,同样的时钟分配。生成代码后下载到板子里居然正常运行了。
我对比了两个软件生成的系统时钟配置文件:system_stm32f1xx.c 。发现有两行代码配置的时钟不一样。
直接将5.3的代码cp到4.27的代码,重新下载4.27代码,还是不行。
于是再对比main.c文件中的SystemClock_Config()和void Error_Handler(void)(注:5.3生成的是这个),void _Error_Handler(char *file, int line) (注4.27生成的是这个)
// 这个是5.3版本cube生成的。
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */
}
// 这个是4.27版本生成的。
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
第二个居然多了一个while(1)循环。索性把这个while(1)循环屏蔽,然后调试。
这下居然成功了,4.27版本的代码成功跑起来了。
但,这到底是为什么呢?难道是以前的Bug?还是我的代码那个地方配置有问题,确实出错了才进入到这个函数处理了?
下一步:把while(1){}的循环放入Cube5.3代码的Error_Handler(),下载运行。果然程序没跑起来,现象和用Cube4.27一个样子。
上面的图片中,两段代码是在5.3版本调试时 增加了while(1) 循环的结果。 同时屏蔽掉是可以运行的。单独屏蔽任意一个还是会进入whil(1)循环。
既然新版本已经去掉了whle(1)循环修正了这部分代码,这应该确实是一个老版本的bug了。在这里记录下来。
喜欢就麻烦你给我点个赞,谢谢。