STM32Cube_FW_F4中HAL_RCC_GetSysClockFreq()的bug
stm32f4xx_hal_rcc.c中 HAL_RCC_GetSysClockFreq()用于获取当前系统时钟,来计算各总线时钟或外设时钟。当HSE_VALUE/pllm结果不是整数时,返回结果有误。
例如:HSE_VALUE = 24000000, pllm=196,plln=14,pllp=2, 原算法结果sysclockfreq=167,999,930,正确结果应该是168,000,000
原因在下面两处计算pllvco时,如果HSE_VALUE/pllm或HSI_VALUE/pllm不能整除时就产生了错误。
|
|
修正:
之前在21ic bbs讨论时有网友有疑问:”为什么不在选择M的时候选一个可以整除的呢?” 因为最佳PLL参数组合并不能保证HSE_VALUE/pllm可整除。参见STM32F4时钟PLL参数计算
目前有发现有Bug的版本:STM32Cube_FW_F4 V1.5.0, V1.6.0, V1.7.0,其它库请自行审查。
Bug影响范围:HAL_RCC_GetSysClockFreq()被HAL_RCC_GetHCLKFreq()调用并更新全局变量SystemCoreClock。而HAL_RCC_GetHCLKFreq()又被HAL_RCC_GetPCLK1Freq()、HAL_RCC_GetPCLK2Freq()调用。
HAL函数库里多个模块会调用以下其一来得到系统时钟或总线时钟:HAL_RCC_GetHCLKFreq(), SystemCoreClock, HAL_RCC_GetPCLK1Freq(),HAL_RCC_GetPCLK2Freq()。
注意到HAL_RCC_GetSysClockFreq()函数定义前面有个weak,表明用户可以自行定义一个同名不带weak的函数,链接时会被替换。因此大家可以根据自己的系统写个简化版的放在项目目录里,毕竟实际应用系统的时钟不会变来变去的。不考虑低功耗的系统时钟一般是固定的,直接返回个固定值也未尝不可。考虑低功耗的,一般两种时钟方案也就够了。