FreeRTOS任务控制API函数的功能分析

目录
  • 1.相对延时
    • 1.1函数描述
    • 1.2参数描述
    • 1.3用法举例
  • 2.绝对延时
    • 2.1函数描述
    • 2.2参数描述
    • 2.3用法举例
  • 3.获取任务优先级
    • 3.1函数描述
    • 3.2参数描述
    • 3.3返回值
    • 3.4用法举例
  • 4.设置任务优先级
    • 4.1函数描述
    • 4.2参数描述
    • 4.3用法举例
  • 5.任务挂起
    • 5.1函数描述
    • 5.2参数描述
    • 5.3用法举例
  • 6.恢复挂起的任务
    • 6.1函数描述
    • 6.2参数描述
  • 7.恢复挂起的任务(在中断服务函数中使用)
    • 7.1函数描述
    • 7.2参数描述
    • 7.3返回值
    • 7.4用法举例

1.相对延时

1.1函数描述

void vTaskDelay( portTickTypexTicksToDelay )

调用vTaskDelay()函数后,任务会进入阻塞状态,持续时间由vTaskDelay()函数的参数xTicksToDelay指定,单位是系统节拍时钟周期。常量portTICK_RATE_MS 用来辅助计算真实时间,此值是系统节拍时钟中断的周期,单位是毫秒。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskDelay 必须设置成1,此函数才能有效。

vTaskDelay()指定的延时时间是从调用vTaskDelay()后开始计算的相对时间。比如vTaskDelay(100),那么从调用vTaskDelay()后,任务进入阻塞状态,经过100个系统时钟节拍周期,任务解除阻塞。因此,vTaskDelay()并不适用与周期性执行任务的场合。此外,其它任务和中断活动,会影响到vTaskDelay()的调用(比如调用前高优先级任务抢占了当前任务),因此会影响任务下一次执行的时间。API函数vTaskDelayUntil()可用于固定频率的延时,它用来延时一个绝对时间。

1.2参数描述

xTicksToDelay:延时时间总数,单位是系统时钟节拍周期。

1.3用法举例

voidvTaskFunction( void * pvParameters )
 {
     /* 阻塞500ms. */
     constportTickType xDelay = 500 / portTICK_RATE_MS;

     for( ;; )
     {
         /* 每隔500ms触发一次LED, 触发后进入阻塞状态 */
         vToggleLED();
         vTaskDelay( xDelay );
     }
}

2.绝对延时

2.1函数描述

void vTaskDelayUntil( TickType_t *pxPreviousWakeTime,const TickType_txTimeIncrement );

任务延时一个指定的时间。周期性任务可以使用此函数,以确保一个恒定的频率执行。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskDelayUntil 必须设置成1,此函数才有效。

这个函数不同于vTaskDelay()函数的一个重要之处在于:vTaskDelay()指定的延时时间是从调用vTaskDelay()之后(执行完该函数)开始算起的,但是vTaskDelayUntil()指定的延时时间是一个绝对时间。

调用vTaskDelay()函数后,任务会进入阻塞状态,持续时间由vTaskDelay()函数的参数指定,单位是系统节拍时钟周期。因此vTaskDelay()并不适用于周期性执行任务的场合。因为调用vTaskDelay()到任务解除阻塞的时间不总是固定的并且该任务下一次调用vTaskDelay()函数的时间也不总是固定的(两次执行同一任务的时间间隔本身就不固定,中断或高优先级任务抢占也可能会改变每一次执行时间)。

vTaskDelay()指定一个从调用vTaskDelay()函数后开始计时,到任务解除阻塞为止的相对时间,而vTaskDelayUntil()指定一个绝对时间,每当时间到达,则解除任务阻塞。

应当指出的是,如果指定的唤醒时间已经达到,vTaskDelayUntil()立刻返回(不会有阻塞)。因此,使用vTaskDelayUntil()周期性执行的任务,无论任何原因(比如,任务临时进入挂起状态)停止了周期性执行,使得任务少运行了一个或多个执行周期,那么需要重新计算所需要的唤醒时间。这可以通过传递给函数的指针参数pxPreviousWake指向的值与当前系统时钟计数值比较来检测,在大多数情况下,这并不是必须的。

常量portTICK_RATE_MS 用来辅助计算真实时间,此值是系统节拍时钟中断的周期,单位是毫秒。

当调用vTaskSuspendAll()函数挂起RTOS调度器时,不可以使用此函数。

2.2参数描述

pxPreviousWakeTime:指针,指向一个变量,该变量保存任务最后一次解除阻塞的时间。第一次使用前,该变量必须初始化为当前时间。之后这个变量会在vTaskDelayUntil()函数内自动更新。

xTimeIncrement:周期循环时间。当时间等于(*pxPreviousWakeTime + xTimeIncrement)时,任务解除阻塞。如果不改变参数xTimeIncrement的值,调用该函数的任务会按照固定频率执行。

2.3用法举例

//每10次系统节拍执行一次
 void vTaskFunction( void * pvParameters )
 {
     static portTickType xLastWakeTime;
     const portTickType xFrequency = 10;
     // 使用当前时间初始化变量xLastWakeTime
     xLastWakeTime = xTaskGetTickCount();
     for( ;; )
     {
         //等待下一个周期
         vTaskDelayUntil( &xLastWakeTime,xFrequency );
         // 需要周期性执行代码放在这里
     }
 }

3.获取任务优先级

3.1函数描述

UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask );

获取指定任务的优先级。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskPriorityGet必须设置成1,此函数才有效。

3.2参数描述

xTask:任务句柄。NULL表示获取当前任务的优先级。

3.3返回值

返回指定任务的优先级。

3.4用法举例

voidvAFunction( void )
 {
     xTaskHandlexHandle;
     // 创建任务,保存任务句柄
     xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ...
     // 使用句柄获取创建的任务的优先级
     if( uxTaskPriorityGet( xHandle ) !=tskIDLE_PRIORITY )
     {
         // 任务可以改变自己的优先级
     }
     // ...
     // 当前任务优先级比创建的任务优先级高?
     if( uxTaskPriorityGet( xHandle ) <uxTaskPriorityGet( NULL ) )
     {
         // 当前优先级较高
     }
 }

4.设置任务优先级

4.1函数描述

void vTaskPrioritySet( TaskHandle_txTask,UBaseType_tuxNewPriority );

设置指定任务的优先级。如果设置的优先级高于当前运行的任务,在函数返回前会进行一次上下文切换。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskPrioritySet 必须设置成1,此函数才有效。

4.2参数描述

xTask:要设置优先级任务的句柄,为NULL表示设置当前运行的任务。uxNewPriority:要设置的新优先级。

4.3用法举例

voidvAFunction( void )
 {
     xTaskHandlexHandle;
     // 创建任务,保存任务句柄。
     xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ...
     // 使用句柄来提高创建任务的优先级
     vTaskPrioritySet( xHandle,tskIDLE_PRIORITY + 1 );
     // ...
     // 使用NULL参数来提高当前任务的优先级,设置成和创建的任务相同。
     vTaskPrioritySet( NULL, tskIDLE_PRIORITY +1 );
 }

5.任务挂起

5.1函数描述

void vTaskSuspend( TaskHandle_txTaskToSuspend );

挂起指定任务。被挂起的任务绝不会得到处理器时间,不管该任务具有什么优先级。

调用vTaskSuspend函数是不会累计的:即使多次调用vTaskSuspend ()函数将一个任务挂起,也只需调用一次vTaskResume ()函数就能使挂起的任务解除挂起状态。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必须设置成1,此函数才有效。

5.2参数描述

xTaskToSuspend:要挂起的任务句柄。为NULL表示挂起当前任务。

5.3用法举例

voidvAFunction( void )
 {
     xTaskHandlexHandle;
     // 创建任务,保存任务句柄.
     xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ...
     // 使用句柄挂起创建的任务.
     vTaskSuspend( xHandle );
     // ...
     // 任务不再运行,除非其它任务调用了vTaskResume(xHandle )
     //...
     // 挂起本任务.
     vTaskSuspend( NULL );
     // 除非另一个任务使用handle调用了vTaskResume,否则永远不会执行到这里
 }

6.恢复挂起的任务

6.1函数描述

void vTaskResume( TaskHandle_txTaskToResume );

恢复挂起的任务。

通过调用一次或多次vTaskSuspend()挂起的任务,可以调用一次vTaskResume ()函数来再次恢复运行。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必须置1,此函数才有效。

6.2参数描述

xTaskToResume:要恢复运行的任务句柄。

6.3用法举例

voidvAFunction( void )
 {
         xTaskHandle xHandle;
     // 创建任务,保存任务句柄
     xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ...
     // 使用句柄挂起创建的任务
     vTaskSuspend( xHandle );
     // ...
     //任务不再运行,除非其它任务调用了vTaskResume(xHandle )
          //...
     // 恢复挂起的任务.
     vTaskResume( xHandle );
     // 任务再一次得到处理器时间
     // 任务优先级与之前相同
 }

7.恢复挂起的任务(在中断服务函数中使用)

7.1函数描述

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume );

用于恢复一个挂起的任务,用在ISR中。

通过调用一次或多次vTaskSuspend()函数而挂起的任务,只需调用一次xTaskResumeFromISR()函数即可恢复运行。

xTaskResumeFromISR()不可用于任务和中断间的同步,如果中断恰巧在任务被挂起之前到达,这就会导致一次中断丢失(任务还没有挂起,调用xTaskResumeFromISR()函数是没有意义的,只能等下一次中断)。这种情况下,可以使用信号量作为同步机制。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须设置成1,此函数才有效。

7.2参数描述

xTaskToResume:要恢复运行的任务句柄。

7.3返回值

如果恢复任务后需要上下文切换返回pdTRUE,否则返回pdFALSE。由ISR确定是否需要上下文切换。

7.4用法举例

xTaskHandlexHandle;               //注意这是一个全局变量
 void vAFunction( void )
     // 创建任务并保存任务句柄
     xTaskCreate( vTaskCode, "NAME",STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ... 剩余代码.
 }
 void vTaskCode( void *pvParameters )
 {
     for( ;; )
     {
         // ... 在这里执行一些其它功能
         // 挂起自己
         vTaskSuspend( NULL );
         //直到ISR恢复它之前,任务会一直挂起
     }
 }
 void vAnExampleISR( void )
 {
     portBASE_TYPExYieldRequired;
     // 恢复被挂起的任务
     xYieldRequired = xTaskResumeFromISR(xHandle );
     if( xYieldRequired == pdTRUE )
     {
         // 我们应该进行一次上下文切换
         // 注:  如何做取决于你具体使用,可查看说明文档和例程
         portYIELD_FROM_ISR();
     }
 }

以上就是FreeRTOS任务控制API函数的功能分析的详细内容,更多关于FreeRTOS任务控制API函数的资料请关注我们其它相关文章!

(0)

相关推荐

  • FreeRTOS编码标准及风格指南

    目录 1.编码标准 2.命名规则 1> 变量 2> 函数 1.编码标准 FreeRTOS的核心源代码遵从MISRA编码标准指南.这个标准篇幅稍长,你可以在MISRA官方网站花少量钱买到,这里不再复制任何标准. FreeRTOS源代码不符合MISRA标准的项目如下所示: 有两个API函数有多个返回点.MISRA编码标准强制规定:一个函数在其结尾应该有单一的返回点. 指针算数运算,在创建任务时,为了兼容8.16.20.24.32位总线,不可避免的使用了指针算数运算.MISRA编码标准强制规定:指针

  • FreeRTOS实时操作系统的内存管理分析

    目录 1.heap_1.c 功能简介: 2.heap_2.c 功能简介: 3.heap_3.c 功能简介: 4.heap_4.c 功能简介: 5.heap_5.c(V8.1.0新增) 前言 本文介绍内存管理的基础知识,详细源码分析见< FreeRTOS内存管理示例分析> FreeRTOS提供了几个内存堆管理方案,有复杂的也有简单的.其中最简单的管理策略也能满足很多应用的要求,比如对安全要求高的应用,这些应用根本不允许动态内存分配的. FreeRTOS也允许你自己实现内存堆管理,甚至允许你同时使

  • FreeRTOS实时操作系统的任务概要讲解

    目录 1. 任务和协程(Co-routines) 1.1任务的特性 1.2任务概要 2. 任务状态 3.任务优先级 4.实现一个任务 5.空闲任务和空闲任务钩子(idle task和Idle Task hook) 5.1空闲任务 5.2空闲任务钩子 1. 任务和协程(Co-routines) 应用程序可以使用任务也可以使用协程,或者两者混合使用,但是任务和协程使用不同的API函数,因此在任务和协程之间不能使用同一个队列或信号量传递数据. 通常情况下,协程仅用在资源非常少的微处理器中,特别是RAM

  • FreeRTOS实时操作系统Cortex-M内核使用注意事项

    前言 在阅读本文之前,有两个定义在FreeRTOSConfig.h中的宏,你必须先明白它们是什么意思,<FreeRTOS内核配置说明>一文中,讲解了这两个宏: configKERNEL_INTERRUPT_PRIORITY configMAX_SYSCALL_INTERRUPT_PRIORITY FreeRTOS与Cortex-M内核可谓是绝配,以至于让移植和使用FreeRTOS都变得更简单起来.根据FreeRTOS官方反馈,在Cortex-M内核上使用FreeRTOS大多数的问题点是由不正确

  • FreeRTOS实时操作系统内核配置说明

    目录 1.configUSE_PREEMPTION 2.configUSE_PORT_OPTIMISED_TASK_SELECTION 3.configUSE_TICKLESS_IDLE 4.configUSE_IDLE_HOOK 5.configUSE_MALLOC_FAILED_HOOK 6.configUSE_TICK_HOOK 7.configCPU_CLOCK_HZ 8.configTICK_RATE_HZ 9.configMAX_PRIORITIES 10.configMINIMAL

  • FreeRTOS动态内存分配管理heap_1示例

    目录 动态内存管理 heap_1.c 内存堆管理 实际可用数组字节数 分配 释放 还剩空闲字节数 动态内存管理 FreeRTOS提供5种动态内存管理策略,分别为heap_1到heap_5,源码在FreeRTOS/Source/portable/MemMang下,本质是对一个或者多个大数组进行操作来对系统提供内存的申请.释放(有的策略没有)功能.下面先看看heap_1是怎么做的. heap_1.c 内存堆管理 大数组在哪里 /* Allocate the memory for the heap.

  • freertos实时操作系统临界段保护开关中断及进入退出

    目录 中断的基础知识 嵌套: 优先级: 中断的悬起与解悬: 咬尾中断Tail‐Chaining: 晚到的高优先级异常: 进入临界段和退出临界段 中断的基础知识 嵌套: 嵌套向量中断控制器 NVIC(Nested Vectored Interrupt Controller与内核是紧耦合的.提供如下的功能:可嵌套中断支持.向量中断支持.动态优先级调整支持.中断延迟大大缩短. 中断可屏蔽. 所有的外部中断和绝大多数系统异常均支持可嵌套中断.异常都可以被赋予不同的优先级,当前优先级被存储在 xPSR的专

  • FreeRTOS任务控制API函数的功能分析

    目录 1.相对延时 1.1函数描述 1.2参数描述 1.3用法举例 2.绝对延时 2.1函数描述 2.2参数描述 2.3用法举例 3.获取任务优先级 3.1函数描述 3.2参数描述 3.3返回值 3.4用法举例 4.设置任务优先级 4.1函数描述 4.2参数描述 4.3用法举例 5.任务挂起 5.1函数描述 5.2参数描述 5.3用法举例 6.恢复挂起的任务 6.1函数描述 6.2参数描述 7.恢复挂起的任务(在中断服务函数中使用) 7.1函数描述 7.2参数描述 7.3返回值 7.4用法举例

  • FreeRTOS实时操作系统队列的API函数讲解

    目录 FreeRTOS为操作队列提供了非常丰富的API函数,包括队列的创建.删除,灵活的入队和出队方式.带中断保护的入队和出队等等.下面就来详细讲述这些API函数. 1.获取队列入队信息数目1.1函数描述 UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue ); 返回队列中存储的信息数目.具有中断保护的版本为uxQueueMessagesWaitingFromISR(),原型为:UBaseType_t uxQueueMessagesW

  • FreeRTOS信号量API函数基础教程

    目录 前言 1创建二进制信号量 1.1函数描述 2创建计数信号量 3创建互斥量 4创建递归互斥量 5删除信号量 6获取信号量 7获取信号量(带中断保护) 8获取递归互斥量 9释放信号量 10释放信号量(带中断保护) 11释放递归互斥量 12获取互斥量持有任务的句柄 前言 FreeRTOS的信号量包括二进制信号量.计数信号量.互斥信号量(以后简称互斥量)和递归互斥信号量(以后简称递归互斥量).我们可以把互斥量和递归互斥量看成特殊的信号量. 信号量API函数实际上都是宏,它使用现有的队列机制.这些宏

  • Windows API函数大全(完整)

    1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同一个网络资源的连接 WNetCancelConnection 结束一个网络连接 WNetCancelConnection2 结束一个网络连接 WNetCloseEnum 结束一次枚举操作 WNetConnectionDialog 启动一个标准对话框,以便建立同网络资源的连接 WNetDisconne

  • VBS调用Windows API函数的代码

    那天无意中搜索到一篇<WinCC VBS利用EXCEL调用Windows API函数>的文章,不知道WinCC是什么,Google了一下好像跟西门子自动化有关.WinCC是什么并不重要,重要的是这篇文章提供了VBS调用Windows API的一种思路--EXCEL VBA,一种传说比VB还要VB的语言. 但是那篇文章中的例子都是使用已经写好的EXCEL VBA程序,即首先得存在一个EXCEL文件.我就想,能不能在VBS中通过excel.application对象创建一个包含VBA代码的EXCE

  • C#调用Win32的API函数--User32.dll

    Win32的API函数是微软自己的东西,可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候我们之直接调用Win32 的API,可以很高效的实现想要的效果. 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace WindowsAPI { class CSharp_

  • javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)

    本文实例讲述了javascript数组对象常用api函数.分享给大家供大家参考,具体如下: 1. concat() 连接两个或多个数组,并返回结果 var a = [1,2,3]; var b = a.concat(6,7); console.log(a); //[1,2,3] console.log(b); //[1,2,3,6,7] 2. join(str) 把数组的所有元素用str分隔,默认逗号分隔 var a = [1,2,3] var b = a.join('|'); console.

  • C# 调用API函数弹出映射网络驱动器对话框问题

    1.基本知识介绍 首先,C#中的.net的常用对话框中没有映射网络驱动映射对话框,所以需要用windows的API函数去实现弹出映射网络驱动器对话框. c#调用API函数的要点可以参考:C#中调用Windows API的技术要点说明 值得注意到是,.net环境下参数类型的声明的不同: a.数值型直接用对应的就可.(DWORD -> int , WORD -> Int16)b.API中字符串指针类型 -> .net中stringc.API中句柄 (dWord)  -> .net中In

  • javascript字符串对象常用api函数小结(连接,替换,分割,转换等)

    本文实例讲述了javascript字符串对象常用api函数.分享给大家供大家参考,具体如下: 1. concat(str1,str2,···) 连接字符串 2. indexOf(str,start) 返回 str 在字符串中首次出现的位置 var str = "hello world"; str.indexOf("hello"); // 0 str.indexOf("o",5); // 7 str.indexOf("World"

  • c#之利用API函数实现动画窗体的方法详解

    这里主要利用API函数Animate Window实现窗体左右,上下,扩展,淡入滑动或滚动动画效果,步骤如下:1.新建窗体,使用2个GroupBox控件.2.在控件1中添加2个RadioButton控件,并设置Text分别为"滚动窗体","滑动窗体",并使前者Checked设置为True.3.在空间2中添加6个按钮,Text分别为"自左向右动画","自右向左动画","自上向下动画","自下向上动画

随机推荐