良许Linux教程网 干货合集 FreeRTOS内核时钟不对的问题解决

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

问题

在使用RTOS时,忽然发现RTOS的时钟出现异常,具体表现在使用vTaskDelay或vTaskDelayUntil函数时,发现延时时间的表现与预期相差甚远,大致为预期时间的10倍左右。

问题定位

经过长时间检查,发现问题出现在configSYSTICK_CLOCK_HZ的定义上。最初理解此宏的意义是:首先,它只适用于Cortex-M处理器;其次,如果Systick和系统时钟相同,就无需定义此宏;但如果两者不同,就需要将其定义为Systick的时钟频率。在移植代码时,采用了以下实现方式:

#define configCPU_CLOCK_HZ                      ( ( unsigned long ) 72000000 )
#define configSYSTICK_CLOCK_HZ                  configCPU_CLOCK_HZ

导致最终的问题。

问题分析

为什么一开始没有发现问题呢,因为一开始仅仅看到了下图,没有对整个设置Systick了解,

image-20240112202706985
image-20240112202706985

看着,觉得设定值没错,然后就是没有看下一句,也没有关注configSYSTICK_CLOCK_HZ这个

宏定义与不定义的区别。在确认问题来源时需要明白两个问题:

1.Systick的时钟是不是就是系统内核时钟,是否可以选择时钟频率

2.Systick是怎样切换系统时钟的

第一个问题

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

image-20240112202730048
image-20240112202730048

第二个问题

很显然第二个问题,自然就出来,通过更改位2即可改变

好,在明确以上两个问题后,我们来问RTOS是如何帮我们设置Systick的

/* Configure SysTick to interrupt at the requested rate. */
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

两句话,没毛病,第一句话设置装在数值,第二步骤设置控制即状态寄存器,好,先按照我原先出现问题情况翻译一下:

/* Configure SysTick to interrupt at the requested rate. */
0xE000_E014 = ( 72000000/ 1000) - 1UL;
0xE000_E010 = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

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

#ifndef configSYSTICK_CLOCK_HZ
 #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
 /* Ensure the SysTick is clocked at the same frequency as the core. */
 #define portNVIC_SYSTICK_CLK_BIT ( 1UL 
#else
 /* The way the SysTick is clocked is not modified in case it is not the same
 as the core. */
 #define portNVIC_SYSTICK_CLK_BIT ( 0 )
#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配置问题,检查每一步配置是否更改相关时钟频率,无须关注其它问题。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部