Freertos任务的管理是何物?

news2024/10/7 18:29:08

Freertos任务的管理


提示:文章来自正点原子和野火

文章目录

  • Freertos任务的管理
  • 前言
  • 一、任务的四种状态
  • 二、 四种状态的关系图
  • 三、函数
    • vTaskSuspend();挂起
    • vTaskResume() ;解挂函数
  • 四、代码示例
  • 总结


前言

使用Freertos,创建任务,运行任务,必须知道怎么配置任务的状态,并将其修改运行的状态,做到想让哪个任务保证必须优先的情况下,也能保证其他任务的实时性。所有要知道任务有几种运行状态,还要知道怎么修改任务的状态。


`

一、任务的四种状态

FreeRTOS 系统中的每一任务都有多种运行状态。系统初始化完成后,创建的任务就可
以在系统中竞争一定的资源,由内核进行调度。
任务状态通常分为以下四种:

  1. 运行态
    如果一个任务得到 CPU 的使用权,即任务被实际执行时,那么这个任务处于运行态。如果
    运行 RTOS 的 MCU 只有一个处理器核心,那么在任务时刻,都只能有一个任务处理运行态。
  2. 就绪态
    如果一个任务已经能够被执行(不处于阻塞态后挂起态),但当前还未被执行(具有相同优
    先级或更高优先级的任务正持有 CPU 使用权),那么这个任务就处于就绪态。
  3. 阻塞态
    如果一个任务因延时一段时间或等待外部事件发生,那么这个任务就处理阻塞态。例如任
    务调用了函数 vTaskDelay(),进行一段时间的延时,那么在延时超时之前,这个任务就处理阻塞
    态。任务也可以处于阻塞态以等待队列、信号量、事件组、通知或信号量等外部事件。通常情
    况下,处于阻塞态的任务都有一个阻塞的超时时间,在任务阻塞达到或超过这个超时时间后,
    即使任务等待的外部事件还没有发生,任务的阻塞态也会被解除。
    要注意的是,处于阻塞态的任务是无法被运行的。
  4. 挂起态
    任务一般通过函数 vTaskSuspend()和函数 vTaskResums()进入和退出挂起态与阻塞态一样,
    处于挂起态的任务也无法被运行。

二、 四种状态的关系图

在这里插入图片描述

三、函数

vTaskSuspend();挂起

FreeRTOS 中的任务也可以进入暂停状态,唯一的方法是通过 vTaskSuspend 函数。函数原型如下:void vTaskSuspend( TaskHandle_t xTaskToSuspend );

vTaskResume() ;解挂函数

挂起态→就绪态 : 把 一 个 挂 起 状态 的 任 务 恢复的 唯 一 途 径 就 是
调 用 vTaskResume() vTaskResumeFromISR() API 函数,

四、代码示例

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );

/* TASK3 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    task3_handler;
void task3( void * pvParameters );
/******************************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
                
    xTaskCreate((TaskFunction_t         )   task3,
                (char *                 )   "task3",
                (configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK3_PRIO,
                (TaskHandle_t *         )   &task3_handler );
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{
    uint32_t task1_num = 0;
    while(1)
    {
        printf("task1_num:%d\r\n",++task1_num);
        LED0_TOGGLE();
        vTaskDelay(500);
    }
}

/* 任务二,实现LED1每500ms翻转一次 */
void task2( void * pvParameters )
{
    uint32_t task2_num = 0;
    while(1)
    {
        printf("task2_num:%d\r\n",++task2_num);
        LED1_TOGGLE();
        vTaskDelay(500);
    }
}

/* 任务三,判断按键KEY0,按下KEY0删除task1 */
void task3( void * pvParameters )
{
    uint8_t key = 0;
    while(1)
    {
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            printf("挂起task1\r\n");
            vTaskSuspend(task1_handler);
        }else if(key == KEY1_PRES)
        {
            printf("在任务中恢复task1\r\n");
            vTaskResume(task1_handler);
        }
        vTaskDelay(10);
    }
}

总结

看图可以明白他们其中的关系,但不使用挂起函数的时候就不会有挂起态,任务只运行在其中的三种状态之中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【1】Spring手写模拟-ApplicationContext获取对象

ApplicationContext获取对象 阶段目标 当前阶段任务,实现ApplicationContext 加载配置文件,实现对配置的包扫描,获取其字节码文件,查看是否包含注需要Spring管理,以及实现单例或者多例获取Bean对象 实现配置文件con…

实现虚拟机(VM15.5.0)与本机相互通信

目录 1、如果虚拟机一打开请先关机 2、进入“控制面板”-“网络和Internet”-“网络连接”,可以看到有两个虚拟网口,关闭虚拟网口VMnet1和VMnet8,如图所示: 3、选择需要通信的虚拟机,点击“编辑虚拟机设置”&#x…

力扣刷题 - 数组篇

这里写目录标题 数组的遍历485495414628 统计数组中的元素64569744844241数组的改变与移动453665---283 二维数组以及滚动数组118119661419--- 数组的旋转189396 特定顺序遍历二维数组5459498 二维数组的变换5664873--- 前缀和数组303238506 数组的遍历 485 https://leetcode.…

【HCIA】07.OSPF

动态路由的协议分类 按工作区域分: IGP(内部网关协议 interior gateway protocols):OSPF、IS-IS、RIPEGP(外部网关协议 exterior gateway protocols):BGP 按工作机制及算法分类: 距离…

机器学习(12)--K-Means

目录 一、聚类 二、机器学习中的距离 三、sklearn中的聚类算法 四、KMeans簇内平方和和时间复杂度 五、sklearn中的KMeans 1、建立一个数据集 2、使用K-Means进行聚类操作 3、根据上面的模型绘散点图观察分类效果。 4、评估指标 4.1对于真实标签已知情况 4.2当真实标…

[RocketMQ] Broker 消息重放服务源码解析 (十三)

构建消息文件ConsumeQueue和IndexFile。 ConsumeQueue: 看作是CommitLog的消息偏移量索引文件, 存储了它所属Topic的消息在Commit Log中的偏移量。消费者拉取消息的时候, 可以从Consume Queue中快速的根据偏移量定位消息在Commit Log中的位置。IndexFile索引文件: 看作是Commi…

【bash:xxx:command not found问题,在英伟达nvidia的jetson-orin-nx上遇到的>>>解决方式之一】

【bash:xxx:command not found问题,在英伟达nvidia的jetson-orin-nx上遇到的>>>解决方式之一】 1、概述2、实验环境3、问题描述:bash:xxx:command not found问题4、我的努力第一种方式:加入指令方式第二种方式:使用echo $PATH命令查…

设计模式(七)-----桥接模式(Bridge Pattern)

目录 什么是桥接模式优点缺点应用场景 基本结构业务场景不使用模式的解决方案实现发送普通消息实现发送加急消息实现发送特急消息添加发送手机消息的处理方式 使用桥梁模式来解决问题 什么是桥接模式 将抽象部分与他的实现部分分离,这样抽象化与实现化解耦,使他们可以独立的变…

Es直方图聚合--date_histogram

文章目录 1、背景2、bucket_key如何计算3、前置知识4、日历和固定时间间隔 4.1 Calendar intervals 日历间隔4.2 Fixed intervals 固定间隔 5、数据准备 5.1 准备mapping5.2 准备数据 6、聚合案例 6.1 dsl6.2 java代码6.3 聚合结果 7、完整代码8、参考文档 1、背景 此处来简单学…

云计算UPS监控,怎么办?

在大型数据机房中,UPS系统扮演着关键的角色,为计算机和网络设备提供可靠的电力备份。由于数据机房的规模庞大且关键性强,监控UPS系统的可靠性和效率至关重要。 UPS监控可以提供实时的电池状态、负载信息、电网电压等监测数据,并能…

c++中assert

参考:https://blog.csdn.net/bitcarmanlee/article/details/124283683 1.什么是assert assert,中文翻译为断言,注意是一个宏定义,不是函数。 c中,要使用assert,可以将cassert头文件include进来,而cassert最…

路径规划算法:基于孔雀优化的路径规划算法- 附代码

路径规划算法:基于孔雀优化的路径规划算法- 附代码 文章目录 路径规划算法:基于孔雀优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法孔雀…

【HCIA】09.STP

STP的选举之发波原理 设备启动之后,经过选举会分别显示出它们的等级(最强,次强,最弱)选出等级之后,两两设备开始互相发波,等级强的设备会将弱的设备的光顶回去此时两两设备之间的波就是单方向的…

家政服务小程序软件解决方案

家政服务小程序软件是近年来随着人们对家政服务需求的增长而逐渐兴起的一种数字化服务解决方案。通过小程序软件,用户可以轻松预约家政服务,包括保姆、月嫂、钟点工等,而且价格透明、服务规范,大大提高了用户对家政服务的满意度。…

神经网络结构可视化-netron

网址:https://netron.app/ 点选择模型,将oonx文件拉到netron界面,即可 输出; 如何将pytorch模型转换为onnx的格式? 在测试(训练好的模型)里输入代码 to_onnx(model, 3, 28, 28, output/params.onnx)其…

【Linux】十分钟理解动静态库

目录 一 前置概念二 静态库2.12.22.3放入指定路径2.4 第三方库的使用 四 动态库3.1 环境变量3.2 软链接方案3.3 配置文件方案 一 前置概念 我们在VS2022下安装开发环境实际上就是安装编译器软件、安装要开发的语言配套的库和头文件。我们使用编译器有语法的自动提醒功能&#…

python常用库之colorama (python命令行界面打印怎么加颜色)

文章目录 python常用库之colorama (python命令行界面打印怎么加颜色)背景colorama介绍colorama使用colorama打印红色闪烁打印颜色组合 python常用库之colorama (python命令行界面打印怎么加颜色) 背景 在Python开发项目过程中,为了方便调试代码,经常会…

Java中Map中10w条数据用什么循环性能最好呢?

加油,新时代打工人! 1、java中List集合三种获取集合元素方式 2、Java中Map使用增强for循环和迭代器获取key和value 选择合适的循环方式,让性能最优! public class Test2 {public static void main(String[] args) {//初始化 10w…

vue upload 上传下载

目录 上传 下载 对象/文件流 download处理返回 文件流 axios.post 封装axios 1.请求设置类型responseType: blob 2.若有请求拦截(直接返回即可) 3.download 4.请求下载 相关基础 blob MIME vue 实现文件上传、下载的方法 - 掘金 上传 submitAddFile(){var form…

基础算法-【离散化】

离散化的本质:是建立了一段数列到自然数之间的映射关系(value -> index),通过建立新索引,来缩小目标区间,使得可以进行一系列连续数组可以进行的操作比如二分,前缀和等… 相应的算法模板: v…