当前位置: 首页 > news >正文

FreeRTOS入门教程(空闲任务和钩子函数及任务调度算法)

文章目录

  • 前言
  • 一、空闲任务概念
  • 二、钩子函数概念
  • 三、任务调度算法
  • 四、任务调度算法实验
    • 1.实验代码
    • 2.是否抢占
    • 3.时间片是否轮转
    • 4.空闲任务让步
  • 总结


前言

本篇文章将带大家学习一下什么是空闲任务以及钩子函数,以及学习FreeRTOS中的任务调度算法,了解在FreeRTOS中任务是如何进行切换调度的。

一、空闲任务概念

空闲任务(Idle Task)是嵌入式实时操作系统(RTOS)中的一种特殊任务。它是系统中优先级最低的任务,并且在系统中没有其他任务需要执行时运行。空闲任务的目的是让处理器在没有其他工作需要执行时保持忙碌状态,从而防止处理器进入空转状态。

空闲任务在RTOS中发挥着重要的作用。当所有其他任务都没有工作要执行时,空闲任务就会运行。它通常执行一些轻量级的操作,如低功耗模式的进入、系统统计信息的更新、调度器的处理等。空闲任务的执行时间应尽量短,以充分利用处理器资源。

空闲任务可以被视为一个后备任务,确保系统始终有任务可以运行,即使没有其他任务就绪。这对于实时系统来说尤为重要,因为实时系统需要对外部事件以及响应用户请求作出快速响应。通过空闲任务,RTOS可以保证系统的连续性和响应性。

在FreeRTOS中,空闲任务是由内核自动创建和管理的。

在使用vTaskStartScheduler开启调度器后会自动的帮我们创建好空闲任务。
在这里插入图片描述

二、钩子函数概念

FreeRTOS 中的钩子函数(Hook Functions)是用户定义的回调函数,用于在 FreeRTOS 内核中特定事件发生时执行自定义的代码。这些钩子函数允许开发者介入 FreeRTOS 的内部操作,以便适应特定的需求、调试或性能分析。

使用钩子函数时需要先开启FreeRTOS中的configUSE_IDLE_HOOK配置宏。

FreeRTOSConfig.h:
在这里插入图片描述

在这里插入图片描述
重新实现钩子函数:

void vApplicationIdleHook( void )
{//用户自定义处理
}

三、任务调度算法

调度算法是操作系统中用于确定进程或线程在可用系统资源上执行的顺序和时间分配的一组规则和策略。调度算法的作用是合理地利用系统资源,提高系统的性能、响应性和效率。

调度算法在多任务操作系统中起着重要的作用,它决定了各个任务之间的执行顺序、分配的时间片长度以及资源的分配策略。

在 FreeRTOS 中,调度算法和行为可以通过一些宏配置来决定,包括 configUSE_PREEMPTION、configUSE_TIME_SLICING 和 configIDLE_SHOULD_YIELD。

1.configUSE_PREEMPTION:

这个宏控制是否启用任务抢占(preemption)。如果设置为 1,则允许具有更高优先级的任务中断当前正在执行的任务;如果设置为 0,则不允许任务抢占。
任务抢占允许更高优先级的任务能够立即获得处理器的控制权,以满足实时需求。然而,抢占会引入上下文切换的开销,可能会对性能产生影响。

2.configUSE_TIME_SLICING:

这个宏用于启用或禁用时间片轮转调度(time slicing)。时间片轮转调度是一种机制,当多个任务具有相同优先级并且可运行时,它们会按时间片的方式轮流使用处理器。
如果设置为 1,则启用时间片轮转调度;如果设置为 0,则禁用时间片轮转调度。

3.configIDLE_SHOULD_YIELD:

这个宏用于配置空闲任务是否应该主动让出处理器。当系统没有其他优先级较高的任务需要运行时,空闲任务会获得处理器的控制权。如果设置为 1,则空闲任务在不需要执行任何其他操作时会主动让出处理器;如果设置为 0,则空闲任务不会主动让出处理器。

如果系统中有其他低优先级任务需要执行,让空闲任务主动让出处理器可以提供更好的响应时间和系统性能。

这里使用百问网提供的一张资料图:
在这里插入图片描述

四、任务调度算法实验

1.实验代码

volatile int flagIdleTaskrun = 0;  // 空闲任务运行时flagIdleTaskrun=1
volatile int flagTask1run = 0;     // 任务1运行时flagTask1run=1
volatile int flagTask2run = 0;     // 任务2运行时flagTask2run=1
volatile int flagTask3run = 0;     // 任务3运行时flagTask3run=1/*-----------------------------------------------------------*/void vTask1( void *pvParameters )
{/* 任务函数的主体一般都是无限循环 */for( ;; ){flagIdleTaskrun = 0;flagTask1run = 1;flagTask2run = 0;flagTask3run = 0;/* 打印任务的信息 */printf("T1\r\n");				}
}void vTask2( void *pvParameters )
{	/* 任务函数的主体一般都是无限循环 */for( ;; ){flagIdleTaskrun = 0;flagTask1run = 0;flagTask2run = 1;flagTask3run = 0;/* 打印任务的信息 */printf("T2\r\n");				}
}void vTask3( void *pvParameters )
{	const TickType_t xDelay5ms = pdMS_TO_TICKS( 5UL );		/* 任务函数的主体一般都是无限循环 */for( ;; ){flagIdleTaskrun = 0;flagTask1run = 0;flagTask2run = 0;flagTask3run = 1;/* 打印任务的信息 */printf("T3\r\n");				// 如果不休眠的话, 其他任务无法得到执行vTaskDelay( xDelay5ms );}
}void vApplicationIdleHook(void)
{flagIdleTaskrun = 1;flagTask1run = 0;flagTask2run = 0;flagTask3run = 0;	/* 故意加入打印让flagIdleTaskrun变为1的时间维持长一点 *///printf("Id\r\n");				
}int main( void )
{prvSetupHardware();xTaskCreate(vTask1, "Task 1", 1000, NULL, 0, NULL);xTaskCreate(vTask2, "Task 2", 1000, NULL, 0, NULL);xTaskCreate(vTask3, "Task 3", 1000, NULL, 2, NULL);/* 启动调度器 */vTaskStartScheduler();/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */return 0;
}

2.是否抢占

抢占:
#define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 1
#define configIDLE_SHOULD_YIELD 1
在这里插入图片描述

不抢占:
#define configUSE_PREEMPTION 0
#define configUSE_TIME_SLICING 1
#define configIDLE_SHOULD_YIELD 1

在这里插入图片描述

这里可以发现当配置为抢占的时候,高优先级的任务就绪后就可以直接执行了。

当配置为不可抢占时,任务会一直执行下去,其他任务无法抢占执行权。

3.时间片是否轮转

支持时间片轮转:

#define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 1
#define configIDLE_SHOULD_YIELD 1

在这里插入图片描述

不支持时间片轮转:

#define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 0
#define configIDLE_SHOULD_YIELD 1

在这里插入图片描述
当配置为支持时间片轮转时,在Tick中断会引起任务的切换。

高优先级任务就绪时会引起任务切换,高优先级任务不再运行时也会引起任务切
换。可以看到任务3就绪后可以马上执行,它运行完毕后导致任务切换。其他时间没有任务切换,
可以看到任务1、任务2都运行了很长时间。

当 FreeRTOS 配置为支持时间片轮转(即 configUSE_TIME_SLICING 设置为 1)时,任务会按照时间片的方式进行调度。每个任务被分配一个时间片,在时间片用尽之前,如果发生 Tick 中断,则会引起任务切换。

4.空闲任务让步

空闲任务让步
#define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 1
#define configIDLE_SHOULD_YIELD 1

在这里插入图片描述

空闲任务不让步
#define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 1
#define configIDLE_SHOULD_YIELD 0

在这里插入图片描述
当配置为空闲任务让步时,可以看出空闲任务运行的时间比较短,会让步给其他任务进行执行。

当配置为空闲任务不让步时,可以看出空闲任务运行的时间和任务1,任务2运行的时间差不多,并不会做出让步。

总结

本篇文章就讲解到这里。

相关文章:

FreeRTOS入门教程(空闲任务和钩子函数及任务调度算法)

文章目录 前言一、空闲任务概念二、钩子函数概念三、任务调度算法四、任务调度算法实验1.实验代码2.是否抢占3.时间片是否轮转4.空闲任务让步 总结 前言 本篇文章将带大家学习一下什么是空闲任务以及钩子函数,以及学习FreeRTOS中的任务调度算法,了解在F…...

Javascript真的是10天内做出来的吗?

我曾听说,Javascript 之所以有这么多缺点,是因为它的第一个版本是在短短十天内完成的。我很好奇:1)这是否属实;2)这是否能解释这种语言的缺陷。 经过一番研究,我可以不自信地说:是的…...

picoctf_2018_got_shell

picoctf_2018_got_shell Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)32位,只开了NX int __cdecl __noreturn main(int argc, const char **argv, const char **envp) {_DWOR…...

作用域 CSS 回来了

几年前,消失的作用域 CSS,如今它回来了,而且比以前的版本要好得多。 更好的是,W3C规范基本稳定,现在Chrome中已经有一个工作原型。我们只需要社区稍微关注一下,引诱其他浏览器构建它们的实现,并…...

简述ceph文件储存系统

Ceph 是一个统一的分布式存储系统和共享机制,它定义了数据如何存储在一个或多个节点上并呈现给其他机器以供文件访问。 Ceph特点 高性能 a. 摒弃了传统的集中式存储元数据寻址的方案,采用CRUSH算法,数据分布均衡,并行度高。 b.考…...

计算机图像处理:椒盐噪声和高斯噪声

图像滤波 图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,同时会造成图像一定程度上的模糊,这也叫做平滑或者低通滤波。无论是均衡化直方图和图像滤波,都一定程度上降低了图像阈值分割的难度,直…...

SQL SELECT 子查询与正则表达式

在之前的文章中已经探讨了 SQL SELECT 语句的基础和进阶用法,以及如何通过高级技巧来进行更复杂的数据查询和分析。本文将介绍 SQL SELECT 语句中的子查询和正则表达式的使用。这些是 SQL 中非常强大的工具,能让您进行更复杂和精细的数据操作。 文章目录 子查询基础与应用子…...

Package vips was not found in the pkg-config search path的解决方案

出现该问题是因为pkg-config未安装或未成功设置环境变量。 下文是centos下的操作。 前提 先安装C编译环境: yum -y install gcc-c 否则会报错configure: error: no acceptable C compiler found in $PATH 成功后gcc -v会显示版本信息。 下载&安装 pkg-config 传…...

Vue封装全局SVG组件

1.SVG图标配置 1.安装插件 npm install vite-plugin-svg-icons -D 2.Vite.config.ts中配置 import { createSvgIconsPlugin } from vite-plugin-svg-icons import path from path export default () > {return {plugins: [createSvgIconsPlugin({// Specify the icon fo…...

课题学习(二)----倾角和方位角的动态测量方法(基于磁场的测量系统)

磁性测量工具安装在非磁性钻铤内,如图1,以避免磁性随钻测量工具测量时受到外部干扰。 测量系统采用三轴加速度计和三轴磁通门,并采用冗余设计,由于井下振动剧烈,陀螺仪的可靠性将大大降低。为了保证整个钻井过程中系统…...

Docker-Windows安装使用

1.下载docker https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 2.配置虚拟化环境 通过控制面板“设置”启用 Hyper-V 角色 右键单击 Windows 按钮并选择“应用和功能”。选择相关设置下右侧的“程序和功能”。选择“打开或关闭 Windows 功能”。选择“Hyper-…...

在Windows11上安装ubuntu虚拟机

一开始是参考了 VMware17虚拟机安装Ubuntu最新版本(Ubuntu22.04LTS)详细步骤 专栏的1和2来的。但是后面总是提示operating system not found,就参考vmware安装ubuntu时总是提示operating system not found,选择典型安装而不是专栏选择的自定义安装&#…...

【微服务】spring 控制bean加载顺序使用详解

目录 一、前言 二、使用order注解控制顺序 2.1 order 注解使用示例 2.2 order注解顺序失效问题 2.2.1 order失效问题解决办法 2.3 实现Ordered接口 三、使用dependon注解控制顺序 四、AutoConfiguration注解控制bean加载顺序 4.1 AutoConfigureBefore 操作演示 4.2 A…...

python-切换镜像源和使用PyCharm进行第三方开源包安装

文章目录 前言python-切换镜像源和使用PyCharm进行第三方开源包安装1. 切换镜像源2. 使用PyCharm进行第三方开源包安装 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说点赞的人每…...

tp6 + swagger 配置文档接口

ThinkPHP 6.0 运行环境要求PHP7.2,兼容PHP8.1 安装 composer create-project topthink/think tp 6.0.*如果需要更新框架使用 composer update topthink/framework文档 完全开发手册 swagger 文档 注解文档 安装包 composer require zircote/swagger-php 引用…...

试图一文彻底讲清 “精准测试”

在软件测试中,我们常常碰到两个基本问题(困难): 很难保障无漏测:我们做了大量测试,但不清楚测得怎样,对软件上线后会不会出问题,没有信心; 选择待执行的测试用例&#…...

Visual Studio 删除行尾空格

1.CtrlH 打开替换窗口(注意选择合适的查找范围) VS2010: VS2017、VS2022: 2.复制下面正则表达式到上面的选择窗口(注意前面有一个空格): VS2010: $ VS2017、VS2022: $ 3.下面的替换窗口不写入 VS2010: VS2017、VS2022: 4.点选“正则表达式…...

LeetCode_BFS_中等_1926.迷宫中离入口最近的出口

目录 1.题目2.思路3.代码实现(Java) 1.题目 给你一个 m x n 的迷宫矩阵 maze (下标从 0 开始),矩阵中有空格子(用 ‘.’ 表示)和墙(用 ‘’ 表示)。同时给你迷宫的入口 …...

开源Windows12网页版HTML源码

开源Windows12网页版HTML源码,无需安装就能用的Win12网页版来了Windows12概念版(PoweredbyPowerPoint)后深受启发,于是通过使用HTML、CSS、js等技术做了这样一个模拟板的Windows12系统,并已发布至github进行开源。 这…...

vscode中使用指定路径下的cmake

在 Visual Studio Code 中指定自定义的 CMake 路径,你可以通过以下步骤来实现: 打开你的 CMake 项目所在的文件夹,在 Visual Studio Code 中。 在项目文件夹中,创建一个名为 .vscode 的文件夹,如果它还不存在。 在 .…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

Vue ③-生命周期 || 脚手架

生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...