以下转载自安富莱电子: http://forum.armfly.com/forum.php

FreeRTOS 的时钟节拍
任何操作系统都需要提供一个时钟节拍,以供系统处理诸如延时、 超时等与时间相关的事件。
时钟节拍是特定的周期性中断,这个中断可以看做是系统心跳。 中断之间的时间间隔取决于不同的应
用,一般是 1ms – 100ms。时钟的节拍中断使得内核可以将任务延迟若干个时钟节拍,以及当任务等待
事件发生时,提供等待超时等依据。时钟节拍率越快,系统的额外开销就越大。
对于 Cortex-M3 内核的 STM32F103 和 Cortex-M4 内核的 STM32F407 以及 F429,教程配套的例
子都是用滴答定时器来实现系统时钟节拍的。

 滴答定时器 Systick
SysTick 定时器被捆绑在 NVIC 中,用于产生 SysTick 异常(异常号: 15), 滴答定时器是一个 24 位
的递减计数器,支持中断。 使用比较简单, 专门用于给操作系统提供时钟节拍。
FreeRTOS 的系统时钟节拍可以在配置文件 FreeRTOSConfig.h 里面设置:
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
如上所示的宏定义配置表示系统时钟节拍是 1KHz,即 1ms。

时间延迟
FreeRTOS 中的时间延迟函数主要有以下两个作用:

 为周期性执行的任务提供延迟。
 对于抢占式调度器,让高优先级任务可以通过时间延迟函数释放 CPU 使用权,从而让低优先级任务可以得到执行。

下面我们通过如下的框图来说明一下延迟函数对任务运行状态的影响,让大家有一个形象的认识。

运行条件:
 仅对任务 Task1 的运行状态做说明。
 调度器支持时间片调度和抢占式调度。
运行过程描述如下:
 起初任务 Task1 处于运行态,调用 vTaskDelay 函数后进入到阻塞状态,也就是 blocked 状态。
 vTaskDelay 函数设置的延迟时间到,由于任务 Task1 不是当前就绪的最高优先级任务,所以不能进
入到运行状态,只能进入到就绪状态,也就是 ready 状态。
 一段时间后, 调度器发现任务 Task1 是当前就绪的最高优先级任务,从而任务从就绪态切换到运行态。
 由于时间片调度,任务 Task1 由运行态切换到就绪态。

FreeRTOS 的时间相关函数
FreeRTOS 时间相关的函数主要有以下 4 个:
 vTaskDelay ()
 vTaskDelayUntil ()
 xTaskGetTickCount()
 xTaskGetTickCountFromISR()

函数 xTaskGetTickCount

函数原型:
volatile TickType_t xTaskGetTickCount( void );
函数描述:
函数 xTaskGetTickCount 用于获取系统当前运行的时钟节拍数。
使用这个函数要注意以下问题:
1. 此函数用于在任务代码里面调用,如果在中断服务程序里面调用的话,需要使用函数
xTaskGetTickCountFromISR,这两个函数切不可混用。

eg:

函数 xTaskGetTickCountFromISR

函数原型:
volatile TickType_t xTaskGetTickCountFromISR( void );
函数描述:
函数 xTaskGetTickCountFromISR 用于获取系统当前运行的时钟节拍数。
使用这个函数要注意以下问题:
1. 此函数用于在中断服务程序里面调用, 如果在任务里面调用的话, 需要使用函数 xTaskGetTickCount,
这两个函数切不可混用。

eg:

void TIM6_IRQHandler( void )
{
TickType_t xTickCount;
xTickCount = xTaskGetTickCountFromISR();

}

函数 vTaskDelay

函数原型:
void vTaskDelay(const TickType_t xTicksToDelay ); /* 延迟时间长度 */

函数描述:
函数 vTaskDelay 用于任务的延迟。
 参数 xTicksToDelay 用于设置延迟的时钟节拍个数,范围 1- 0xFFFFFFFF。 延迟时间的最大值在
portmacro.h 文件里面有定义:
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t )0xffffffffUL
即延迟时间的范围是:1- 0xFFFFFFFF

函数 vTaskDelayUntil
函数原型:
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, /* 存储任务上次处于非阻塞状态时刻的变量地址 */
const TickType_t xTimeIncrement ); /* 周期性延迟时间 */
函数描述:
函数 vTaskDelayUntil 用于周期性延迟。
 第 1 个参数,存储任务上次处于非阻塞状态时刻的变量地址。
 第 2 个参数,周期性延迟时间。
使用这个函数要注意以下问题:
1. 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1
#define INCLUDE_vTaskDelayUntil 1

函数 vTaskDelay 和 vTaskDelayUntil 的区别
函数 vTaskDelayUntil 实现的是周期性延迟,而函数 vTaskDelay 实现的是相对性延迟,反映到实际
应用上有什么区别呢,下面就给大家举一个简单的例子。
运行条件:
 有一个 bsp_KeyScan 函数,这个函数处理时间大概耗时 2ms。
 有两个任务,一个任务 Task1 是用的 vTaskDelay 延迟,延迟 10ms,另一个任务 Task2 是用的
vTaskDelayUntil 延迟,延迟 10ms。
 不考虑任务被抢占而造成的影响

eg1:绝对延时vTaskDelayUntil函数实现

static void vTaskLED(void *pvParameters)
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = 200; /* 获取当前的系统时间 */
xLastWakeTime = xTaskGetTickCount(); while()
{
bsp_LedToggle(); /* vTaskDelayUntil是绝对延迟,vTaskDelay是相对延迟。*/
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}

eg2:绝对延时vTaskDelay函数实现

static void vTaskMsgPro(void *pvParameters)
{
TickType_t xDelay, xNextTime;
const TickType_t xFrequency = 200; /* 获取xFrequency个时钟节拍后的时间 */
xNextTime = xTaskGetTickCount() + xFrequency; while()
{
bsp_LedToggle(); /* 用vTaskDelay实现vTaskDelayUntil() */
xDelay = xNextTime - xTaskGetTickCount();
xNextTime += xFrequency; if(xDelay <= xFrequency)
{
vTaskDelay(xDelay);
}
}
}

要理解eg2需要破费心思。

想要用相对延时的方式实现绝对延时,我们首先获取当前系统节拍,并且加上200个节拍,在我的测试例子中,一个节拍是1ms。这说明我是想要实现一个200ms的周期性任务。在执行完led翻转之后,我获取当前节拍数,用之前保存的想要延时数xNextTime减去当前节拍,得到的这个节拍就应该是我们用相对延时vTaskDelay去延时的时间。但是为什么程序实现中还要加上xNextTime += xFrequency;和一个if判断if(xDelay <= xFrequency)呢?(当xNextTime 减去xTaskGetTickCount()减得够的时候,if条件是肯定满足的,而此时xNextTime += xFrequency是为了给下一个周期的nexttime赋值一个固定的时钟节拍,这里是200).但是,有个问题需要注意,要是我的不是一个简单的led任务,而是一段运行时间超过200ms的程序呢?这样会导致 xNextTime - xTaskGetTickCount();得到一个小于0的数,但是定义的无符号类型,会发生有符号到无符号的转换,这个时候,程序就会出错(此时的delay函数不再准确),和其他任何定时器任务一样,周期性任务设计的时候,应该确保在周期内完成任务工作。

FreeRTOS 系统时钟节拍和时间管理的更多相关文章

  1. RTX——第12章 系统时钟节拍和时间管理

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 RTX 操作系统的时钟节拍和时间管理函数,其中时间管理函数是 RTX 的基本函数,初学 ...

  2. uC/OS-III 时钟节拍,时间管理,时间片调度

    uC/OS-III 时钟节拍,时间管理,时间片调度   时钟节拍 时钟节拍可谓是 uC/OS 操作系统的心脏,它若不跳动,整个系统都将会瘫痪. 时钟节拍就是操作系统的时基,操作系统要实现时间上的管理, ...

  3. FreeRTOS学习笔记4:时间管理

    绝对时间:abs Time相对时间:百分比% time IDLE是空闲任务. RUN_Time_State:port...()初始化一个外设提供时基单元 //具体初始化要自己操作这个定时器的分辨率高于 ...

  4. FreeRTOS-04-内核控制函数+时间管理函数

    说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...

  5. liteos时间管理(九)

    1. 时间管理 1.1 概述 1.1.1 概念 时间管理以系统时钟为基础.时间管理提供给应用程序所有和时间有关的服务. 系统时钟是由定时/计数器产生的输出脉冲触发中断而产生的,一般定义为整数或长整数. ...

  6. uC/OS-III 时间管理(二)

    时间管理就是一种建立在时钟节拍上,对操作系统任务的运行实现时间上管理的一种系统内核机制. 常用以下五个函数: OSTimeDly() OSTimeDlyHMSM() OSTimeDlyResume() ...

  7. RT-thread内核之系统时钟

    一.系统时钟 rt-thread的系统时钟模块采用全局变量rt_tick作为系统时钟节拍,该变量在系统时钟中断函数中不断加1.而系统时钟中断源和中断间隔一般由MCU硬件定时器(如stm32的嘀嗒定时器 ...

  8. FreeRTOS时间管理

    延时函数 vTaskDelay() 相对延时函数,在文件task.c中定义的,要使用的话宏INCLUDE_vTaskDelay必须设置为1: void vTaskDelay( const TickTy ...

  9. 【uTenux实验】时间管理(系统时间/周期性处理/警报处理)

    1.系统时间管理 系统时间管理函数用来对系统时间进行操作,是OS的一个基础性的东西.个人认为,设置系统时间和获取系统时间对OS来说基本是可有可无的. uTenux提供了三个系统时间相关API.分别用于 ...

随机推荐

  1. Resin install document

    Centos6快速安装文档 resin3.1.13 软件下载地址: http://caucho.com/products/resin/download/gpl#download #系统环境[root@ ...

  2. 什么是vBlock

    Vblock产品是指一种建立系统的方式,Vblock提供的是一个集成包,是一种完整的IT基础架构,并不是一个具体的设备. 具体点就是:Vblock是一个融合了思科服务器与网络.EMC存储系统与管理软件 ...

  3. Android -- Sqlite事务

    这也是通过Android Juint来实现的. 基于上一次的工程继续,上一次工程传送门:<Android–Android Juint 与 Sqlite> http://www.cnblog ...

  4. angularjs中ajax请求时传递参数的方法

    method1方法使用的是params参数,该用法会把参数直接附加到url中 method2方法使用的是data参数,该参数会把页面参数类型从默认的multipart/form-data改为appli ...

  5. 微信小程序 - 贝塞尔曲线(购物车效果)

    转载来源于:https://segmentfault.com/a/1190000011710786 简化了一下,发出来吧 示例源码:点击下载

  6. UNIX网络编程读书笔记:名字与地址转换

    概述 在名字和数值地址间进行转换的函数: gethostbyname和gethostbyaddr:在主机名字与IPv4地址之间进行转换.仅仅支持IPv4. getservbyname和getservb ...

  7. 彻底告别加解密模块代码拷贝-JCE核心Cpiher详解

    前提 javax.crypto.Cipher,翻译为密码,其实叫做密码器更加合适.Cipher是JCA(Java Cryptographic Extension,Java加密扩展)的核心,提供基于多种 ...

  8. wap、app移动端页面常用html标签汇总

    1.section 将内容组织到精确的语义块,表示页面的一部分. 2.article article表示网页的一个文章.故事. 3.header (1)用在整页的页头 (2)section或者arti ...

  9. Android SDK 更新和下载慢怎么办?

    博客搬家:因为各种原因,我如今的博客将首发于blog.mojijs.com, 能够百度搜索 "姜哥的墨迹技术博客" , 或者 点击这里 本文地址 http://blog.mojij ...

  10. eclipse maven Cannot change version of project facet Dynamic web module to 3.0

      eclipse maven Cannot change version of project facet Dynamic web module to 3.0 (eclipse 修改maven项目的 ...