0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FreeRTOS任务控制API函数介绍

安芯教育科技 来源:极术社区 作者:朱工 2021-03-19 10:19 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

FreeRTOS任务控制API函数主要实现任务延时、任务挂起、解除任务挂起、任务优先级获取和设置等功能。

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系列第11篇---FreeRTOS任务控制

文章出处:【微信公众号:安芯教育科技】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RTOS
    +关注

    关注

    25

    文章

    862

    浏览量

    122611
  • FreeRTOS
    +关注

    关注

    14

    文章

    497

    浏览量

    66355

原文标题:FreeRTOS系列第11篇---FreeRTOS任务控制

文章出处:【微信号:Ithingedu,微信公众号:安芯教育科技】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    ucos与freertos哪个好?

    选择uCOS或FreeRTOS取决于项目的具体需求和资源限制。 FreeRTOS的优点包括: 更小的内核ROM和RAM占用,特别是在RAM方面,适合资源受限的嵌入式系统。 支持协程
    发表于 12-05 07:13

    FreeRTOS 空闲任务

    FreeRTOS 中很多人会注意到为什么有一个叫IDLE task的任务占用了CPU百分之九十多的使用权,但是这个任务并没有自己手动创建。原因就是这个空闲任务是系统自己创建的,每当系统
    发表于 12-04 07:35

    freertos关闭任务调度的方法

    #include \"FreeRTOS.h\" #include \"task.h\" /* 关闭任务调度 */ void
    发表于 11-17 06:47

    FreeRTOS任务调度及优先级问题

    大家好,最近本人在学习FreeRTOS ,之前有过一些裸机开发的经验,目前知道了FreeRTOS任务是基于时间片轮转来调度,也就是知道了任务会基于各个时间片来运行。 于是联想了如果有
    发表于 11-06 02:18

    小红书API接口的应用场景介绍

    ,逐步介绍小红书API的典型应用场景,帮助您理解其实际用途。这些场景基于社交平台API的通用设计,确保真实可
    的头像 发表于 11-04 15:03 249次阅读
    小红书<b class='flag-5'>API</b>接口的应用场景<b class='flag-5'>介绍</b>

    代购系统 API 介绍

    1. 用户相关 API 用户注册 POST /api/users/register 参数:username, email, password, phone 返回:user_id, token 用户
    的头像 发表于 10-08 09:21 151次阅读

    京东API 介绍

    京东 API 是京东开放平台提供的一组标准化接口,允许开发者通过程序化方式访问京东生态的核心业务能力,涵盖商品、订单、物流、金融、智能客服等多个领域。以下是基于最新技术规范的详细介绍: 一、核心
    的头像 发表于 10-08 09:04 350次阅读

    FreeRTOS任务中发送事件队列是有什么限制吗?

    任务发送事件告知运动完成。 因为板卡有六路电机,每一路单独控制的时候没有什么问题。但是多路运行特别是多路复位的时候有的电机会卡死,查询电机状态显示运行中,通过DEBUG发现每一路的电机复位指令下发
    发表于 06-11 07:57

    详解FreeRTOS与SAFERTOS的区别

    开源免费的FreeRTOS由Richard Barry在WHIS工作时创建,WHIS基于FreeRTOS的功能模型,通过完整的HAZOP分析,确定了功能模型和API中的所有的弱点,减轻所有薄弱环节,并采用IEC 61508 SI
    的头像 发表于 06-04 16:58 685次阅读
    详解<b class='flag-5'>FreeRTOS</b>与SAFERTOS的区别

    迅为RK3568开发板驱动指南GPIO子系统GPIO子系统API函数的引入

    迅为RK3568开发板驱动指南GPIO子系统GPIO子系统API函数的引入
    的头像 发表于 05-29 14:05 834次阅读
    迅为RK3568开发板驱动指南GPIO子系统GPIO子系统<b class='flag-5'>API</b><b class='flag-5'>函数</b>的引入

    FreeRTOS读取ADS1299数据有误

    vTaskDelay(1) 在发送任务中:读取队列中的数据——发送到上位机 但是数据会出错,正常数据的范围是-1到1,用freertos就会出现超出正常范围的数据, 而在main函数的主循环中采集数据、滤波、发送到上位机就
    发表于 05-05 22:48

    ZU+RFSoC之RFDC API介绍和使用

    RF Data Converters驱动API是AMD Xilinx为RFSoC提供的一套软件接口,用于控制Data Converters(RF-ADC和RF-DAC)的硬件功能。它作为用户应用程序
    的头像 发表于 04-16 10:05 2785次阅读
    ZU+RFSoC之RFDC <b class='flag-5'>API</b><b class='flag-5'>介绍</b>和使用

    详解RTOS中的Hook函数

    Hook函数是RTOS中的一个关键特性,通过该函数,用户可以增强对任务管理的控制,定义系统行为。
    的头像 发表于 03-24 16:14 839次阅读

    移植LWIP+FREERTOS时遇到的问题怎么解决?

    :将ST官网的LWIP1.4.1 的例子(关于LWIP的部分)移植到步骤1 的FreeRTOS 系统的工程里面,只是添加LWIP初始化的任务,并没有调用任何接口的情况下可以Ping 通 而且长时间
    发表于 03-11 06:48

    如何找到DLP4500的API函数库和说明手册?

    您好,我买了一块DLP4500,我是想采用C#编程,想通过调用API函数来重建点云。(C#如何调用API我会) 我看了很多资料,都是一些C++的例子,都没有理出头绪,麻烦指点一下。 重建点云,可以直接调用的
    发表于 03-03 06:18