谷动谷力

 找回密码
 立即注册
查看: 6117|回复: 0
打印 上一主题 下一主题
收起左侧

FreeRTOS内核时钟不对的问题解决

[复制链接]
跳转到指定楼层
楼主
发表于 2022-6-24 22:58:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
FreeRTOS内核时钟不对的问题解决问题


在使用RTOS时,突然发现RTOS的时钟不太对劲,具体表现在使用vTaskDelay或vTaskDelayUntil时发现延时时间并不对,大致为目标的10倍左右。

问题定位

在检查许久后发现问题在configSYSTICK_CLOCK_HZ,这个定义上。原先对于这个宏的原始理解就是,首先只针对Cortex-M可用,然后就是如果Systick和系统时钟一样就无须定义,不一样时定义成Systick的时钟频率,然后移植时就是索性使用了以下方式:
  1. #define configCPU_CLOCK_HZ           ( ( unsigned long ) 72000000 )
  2. #define configSYSTICK_CLOCK_HZ    configCPU_CLOCK_HZ
复制代码

导致最终的问题。

问题分析

为什么一开始没有发现问题呢,因为一开始仅仅看到了下图,没有对整个设置Systick了解,
看着,觉得设定值没错,然后就是没有看下一句,也没有关注configSYSTICK_CLOCK_HZ这个
宏定义与不定义的区别。在确认问题来源时需要明白两个问题:
1.Systick的时钟是不是就是系统内核时钟,是否可以选择时钟频率
2.Systick是怎样切换系统时钟的

第一个问题

Systick的时钟不一定是系统时钟(AHB),找到CM内核可以看到Systick寄存器,中2位的类型,即可明确,有两种情况1是内核时钟,0是内核时钟的8分频


第二个问题

很显然第二个问题,自然就出来,通过更改位2即可改变
好,在明确以上两个问题后,我们来问RTOS是如何帮我们设置Systick的
  1. /* Configure SysTick to interrupt at the requested rate. */

  2. portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;

  3. portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
复制代码


两句话,没毛病,第一句话设置装在数值,第二步骤设置控制即状态寄存器,好,先按照我原先出现问题情况翻译一下:
  1. /* Configure SysTick to interrupt at the requested rate. */

  2. 0xE000_E014 = ( 72000000/ 1000) - 1UL;

  3. 0xE000_E010 = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
复制代码


只关注到重装寄存器数据的正确性,忽略了控制与状态寄存器的配置,当关注到这个问题了自然就解决了,首先找下portNVIC_SYSTICK_CLK_BIT 定义
  1. #ifndef configSYSTICK_CLOCK_HZ
  2. #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ

  3. /* Ensure the SysTick is clocked at the same frequency as the core. */

  4. #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )

  5. #else

  6. /* The way the SysTick is clocked is not modified in case it is not the same

  7. as the core. */

  8. #define portNVIC_SYSTICK_CLK_BIT ( 0 )

  9. #endif
复制代码


看到了没,如果定义了configSYSTICK_CLOCK_HZ就会更改portNVIC_SYSTICK_CLK_BIT的数值,即使你保证了configSYSTICK_CLOCK_HZ和系统时钟频率是一样的也不行,会导致时钟源的时钟源发生改变,导致最终的问题。

解决办法

怎么样完美解决还是去官网看下这宏的本身官方解释:
取消定义configSYSTICK_CLOCK_HZ
Optional parameter for ARM Cortex-M ports only.
By default ARM Cortex-M ports generate the RTOS tick interrupt from the Cortex-M SysTick timer. Most Cortex-M MCUs run the SysTick timer at the same frequency as the MCU itself - when that is the case configSYSTICK_CLOCK_HZ is not needed and should be left undefined. If the SysTick timer is clocked at a different frequency to the MCU core then set configCPU_CLOCK_HZ to the MCU clock frequency, as normal, and configSYSTICK_CLOCK_HZ to the SysTick clock frequency.

大致意思就是仅对Cortex-M内核有效,其次就是如果Systick系统的时钟和内核一样那就不要去定定义这个宏,反之就定义这个宏,同时将其数值分频后的实际时钟频率。
那就很简单了,移除对其定义就好了。

总结

在RTOS中如果出现RTOS内核时钟不对,首先定位Systick配置问题,检查每一步配置是否更改相关时钟频率,无须关注其它问题。



+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-12-28 15:30 , Processed in 0.088467 second(s), 42 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表