第17章
FreeRTOS系统时钟节拍和时间管理
本文完整版地址:http://bbs.armfly.com/read.php?tid=21196
本章节为大家讲解FreeRTOS操作系统的系统时钟节拍和时间管理函数,其中时间管理函数是FreeRTOS的基本函数,初学者务必要掌握。
本章教程配套的例子含Cortex-M3内核的STM32F103和Cortex-M4内核的STM32F407以及F429。
17.1
FreeRTOS的时钟节拍
17.2
FreeRTOS的时间管理
17.3
实验例程说明
17.4
总结
17.1 FreeRTOS的时钟节拍
任何操作系统都需要提供一个时钟节拍,以供系统处理诸如延时、超时等与时间相关的事件。
时钟节拍是特定的周期性中断,这个中断可以看做是系统心跳。中断之间的时间间隔取决于不同的应用,一般是1ms
–
100ms。时钟的节拍中断使得内核可以将任务延迟若干个时钟节拍,以及当任务等待事件发生时,提供等待超时等依据。时钟节拍率越快,系统的额外开销就越大。
对于Cortex-M3内核的STM32F103和Cortex-M4内核的STM32F407以及F429,教程配套的例子都是用滴答定时器来实现系统时钟节拍的。
l
滴答定时器Systick
SysTick定时器被捆绑在NVIC中,用于产生SysTick异常(异常号:15),滴答定时器是一个24位
的递减计数器,支持中断。使用比较简单,专门用于给操作系统提供时钟节拍。
FreeRTOS的系统时钟节拍可以在配置文件FreeRTOSConfig.h里面设置:
#define
configTICK_RATE_HZ ( ( TickType_t ) 1000 )
如上所示的宏定义配置表示系统时钟节拍是1KHz,即1ms。
17.2FreeRTOS的时间管理
时间管理功能是FreeRTOS操作系统里面最基本的功能,同时也是必须要掌握好的。
17.2.1时间延迟
FreeRTOS中的时间延迟函数主要有以下两个作用:
u
为周期性执行的任务提供延迟。
u
对于抢占式调度器,让高优先级任务可以通过时间延迟函数释放CPU使用权,从而让低优先级任务可以得到执行。
下面我们通过如下的框图来说明一下延迟函数对任务运行状态的影响,让大家有一个形象的认识。
运行条件:
u
仅对任务Task1的运行状态做说明。
u
调度器支持时间片调度和抢占式调度。
运行过程描述如下:
u
起初任务Task1处于运行态,调用vTaskDelay函数后进入到阻塞状态,也就是blocked状态。
u
vTaskDelay函数设置的延迟时间到,由于任务Task1不是当前就绪的最高优先级任务,所以不能进入到运行状态,只能进入到就绪状态,也就是ready状态。
u
一段时间后,调度器发现任务Task1是当前就绪的最高优先级任务,从而任务从就绪态切换到运行态。
u
由于时间片调度,任务Task1由运行态切换到就绪态。
上面就是一个简单的任务运行状态的切换过程。
17.2.2FreeRTOS的时间相关函数
FreeRTOS时间相关的函数主要有以下4个:
u
vTaskDelay
()
u
vTaskDelayUntil
()
u
xTaskGetTickCount()
u
xTaskGetTickCountFromISR()
下面我们对这4个函数依次进行说明:
17.2.3函数vTaskDelay
关于这个函数的讲解及其使用方法可以看FreeRTOS在线版手册:
这里也对此函数进行下介绍。
函数原型:
void
vTaskDelay(
const TickType_t xTicksToDelay );
函数描述:
函数vTaskDelay用于任务的延迟。
u
参数xTicksToDelay用于设置延迟的时钟节拍个数,范围1-
0xFFFFFFFF。延迟时间的最大值在portmacro.h文件里面有定义:
typedef uint32_t
TickType_t;
#define
portMAX_DELAY ( TickType_t )0xffffffffUL
即延迟时间的范围是:1-
0xFFFFFFFF
使用举例:
static
void vTaskLED(void *pvParameters)
{
while(1)
{
bsp_LedToggle(2);
vTaskDelay(200);
}
}
17.2.4函数vTaskDelayUntil
关于这个函数的讲解及其使用方法可以看FreeRTOS在线版手册:
这里也对此函数进行下介绍。
函数原型:
void
vTaskDelayUntil( TickType_t
*pxPreviousWakeTime,
const TickType_t xTimeIncrement );
函数描述:
函数vTaskDelayUntil用于周期性延迟。
u
第1个参数,存储任务上次处于非阻塞状态时刻的变量地址。
u
第2个参数,周期性延迟时间。
使用这个函数要注意以下问题:
1.
使用此函数需要在FreeRTOSConfig.h配置文件中配置如下宏定义为1
#define
INCLUDE_vTaskDelayUntil 1
2.
用户要注意此函数跟vTaskDelay的区别,本章17.2.7小节详细讲解。
使用举例:
static
void vTaskLED(void *pvParameters)
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = 200;
xLastWakeTime = xTaskGetTickCount();
while(1)
{
bsp_LedToggle(2);
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}
17.2.5函数xTaskGetTickCount
关于这个函数的讲解及其使用方法可以看FreeRTOS在线版手册:
这里也对此函数进行下介绍。
函数原型:
volatile
TickType_t xTaskGetTickCount( void );
函数描述:
函数xTaskGetTickCount用于获取系统当前运行的时钟节拍数。
使用这个函数要注意以下问题:
1. 此函数用于在任务代码里面调用,如果在中断服务程序里面调用的话,需要使用函数xTaskGetTickCountFromISR,这两个函数切不可混用。
使用举例:
static
void vTaskTaskUserIF(void *pvParameters)
{
uint8_t ucKeyCode;
uint8_t pcWriteBuffer[500];
<