参考文章1:《FreeRTOS的学习(六)——系统时钟》
参考文章2:【FreeRTOS】04 系统的时钟节拍和延时函数
原理
reeRTOS使用裸机自带的滴答定时器中断,使用其主频或者外部频率作为时钟基准。由于定时器的功能作为FreeRTOS的核心,所以正常情况下必须是一个一直运行着的中断,那么就意味着FreeRTOS庞大的代码量也必须与此中断相互配合,保证实时性和可靠性,因此滴答定时器的中断时间必然是不能太短的,否则将大大影响FreeRTOS的实时性。我们直接来看配置的代码:
1 void delay_init() 2 { 3 u32 reload; 4 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择内部时钟 HCLK 5 fac_us=SystemCoreClock/1000000; //不论是否使用OS,fac_us都需要使用 7 reload=SystemCoreClock/configTICK_RATE_HZ; //根据configTICK_RATE_HZ设定溢出时间 8 //reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右 9 fac_ms=1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位 10 11 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 12 SysTick->LOAD=reload; //每1/configTICK_RATE_HZ秒中断一次 13 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK 14 }
通过控制SysTick寄存器的几个地址可以实现开启中断,设定中断频率,开启/关闭SysTick的功能。
其中,reload作为中断的频率,其计算过程较为重要,需要根据系统时钟设定。本人使用的是stm32f103,系统主频为72M,那么也就意味着,stm32在1s内可以计数72M个。那么只要控制reload的值,每次计数结束后产生一次中断就可以了。所以引入configTICK_RATE_HZ的变量,用于方便调整滴答定时器的中断频率。具体的计算相对简单,可自行尝试。
FreeRTOS通过全局变量xTickCount的计数以及在SysTick的中断函数里的操作与逻辑之间形成了联系。下面给出了**SysTick_Handler()**的中断内部函数:
1 void SysTick_Handler(void) 2 { 3 if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//判断系统是否已经运行 4 { 5 xPortSysTickHandler(); 6 } 7 }
1 void xPortSysTickHandler( void ) 2 { 3 //执行SysTick_Handler中断函数时,为了保证在freertos中属于最低优先级的此中断能顺利执行, 4 //故要关闭FreeRTOS的所有可管理中断,保证系统计数时不被打断。 5 vPortRaiseBASEPRI(); //关中断 6 { 7 if( xTaskIncrementTick() != pdFALSE ) //判断返回值,如果为pdTURE就要进行一次上下文切换 8 { 9 portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; 10 } 11 } 12 vPortClearBASEPRIFromISR(); //开中断 13 }
为了保证计数的正常执行,需要先关闭系统中断,但是值得注意的是,FreeRTOS系统可关闭的中断都是系统级的,一般还有优先级在5以上的几个中断不受其管理,具体可见之前写的中断机制相关内容。那么也就不可避免地,计数会被这种情况打断,至少目前为止,以我学习到的内容来考虑,使用了RTOS就不太适合使用其他高优先级的大段大段主体内容的中断函数了,会对RTOS的运行产生极大的影响。所以系统外的高优先级中断一般都是短且对实时性要求高的,用于诸如一些紧急情况,需要紧急处理的。
系统的滴答定时器中断像是定时检查的功能,主要是列表溢出检查,任务唤醒检查,是否唤醒的任务要进行调度或者抢占式任务要进行调度等功能。
应用
操作系统的时钟节拍,是用于系统计时的;有了时钟节拍这个计时器,操作系统就能知道时间过去了多少周期,便于处理延时、超时等等与时间相关的操作。
一般情况下,时钟节拍是一个定时器中断,周期性地进入中断更新计数器,以计数器的值去指示走过了多少节拍。
时钟节拍的周期需要依据具体任务的特点来确定,一般为1ms~100ms。如果实时性要求高,需要任务响应较快,则节拍设置得短一些;如果实时性要求低,可以设置得长一些。如果设置的节拍短,那么系统对时间的控制更精确,比如设置成1ms,那么延时的精度可以达到最小1ms;设置成10ms节拍,系统就无法实现1ms的延时;但是,时钟节拍设置得越短,则系统自身的开销会越大。
FreeRTOS的时钟节拍可以在keil工程中的FreeRTOSConfig.h文件中设置:
图中设置成了1000Hz,也就是1ms一个节拍。
在使用cubemx生成keil工程时,也可以在这里修改,最后同样会体现在生成的FreeRTOSConfig.h文件中:
标签:FreeRTOS,中断,节拍,延时,SysTick,复盘,时钟 From: https://www.cnblogs.com/FBsharl/p/17507819.html