FreeRTOS任务调度器

目录

1、什么是任务调度器

 2、FreeRTOS中的任务调度器

2.1 抢占式调度

2.2 时间片调度

2.3 协作式调度

3、任务调度案例分析

3.1 实验需求

3.2 CubeMX配置

3.3 代码实现

3.3.1 uart.c 重定向printf

3.3.2 打开freertos.c并添加代码

3.3.4 代码现象


1、什么是任务调度器

任务调度器是实时操作系统(RTOS)的一个关键组件,它负责决定在多个可运行任务中哪一个将获得CPU时间得以执行。它基于任务的优先级和状态来做出这些决定。

在一个RTOS中,可能会有多个任务同时运行,但是在任意时刻,CPU只能执行一个任务。任务调度器的主要目标是按照系统的需求合理分配CPU时间

调度器就是使用相关的调度算法来决定当前需要执行的哪个任务

基本功能

任务的选择任务调度器会根据预设的算法从所有可运行的任务中选择一个要执行的任务
任务的优先级任务通常会被分配一个优先级,优先级越高的任务在抢占式调度中会优先执行
任务状态管理任务可能处于就绪状态(可立即运行)、阻塞状态(等待某些条件满足)或者挂起状态(暂停执行)。
上下文切换任务调度器负责在不同任务之间进行上下文切换。这意味着将当前任务的状态保存起来,然后加载另一个任务的状态,以便它可以继续执行。
定时器管理任务调度器通常会关注系统中的定时器,以便能够在特定事件发生时唤醒相应的任务
中断处理任务调度器需要与系统的中断处理程序协同工作,以确保在中断上下文中也能够正常进行任务调度

 2、FreeRTOS中的任务调度器

FreeRTOS 是一个实时操作系统,它所奉行的调度规则:

1. 抢占式调度器:抢占式调度器是一种优先级基础的调度器,高优先级抢占低优先级任务,系统永远执行最高优先级的任务。

2. 时间片调度器:时间片轮转调度器是一种抢占式调度器,它将CPU时间划分成小的时间片段,每个任务在一个时间片段内运行

3. 协程式调度器:协作式调度器依赖于任务自行释放CPU,没有明确的任务优先级任务必须自愿放弃CPU控制权,以便其他任务能够运行。(但官方已明确表示不更新,主要是用在小容量的芯片上,用得也不多)

FreeRTOS中开启任务调度的函数是vTaskStartScheduler() ,但在CubeMX中被封装为osKernelStart() 。

2.1 抢占式调度

优点适用于实时要求严格的系统,可以确保高优先级任务及时响应。
缺点上下文切换的开销较大,可能会影响系统的性能。

        1. 任务优先级:每个任务都会被分配一个优先级。优先级较高的任务被认为更紧急,将会在可运行时抢占具有较低优先级的任务

        2. 抢占:当一个高优先级的任务准备好运行时,RTOS会暂停当前正在执行的低优先级任务,并将CPU的控制权转交给高优先级任务

        3. 上下文切换:在抢占发生时,RTOS会保存当前任务的上下文(包括寄存器状态等),然后加载高优先级任务的上下文,使其可以继续执行。这个过程称为上下文切换。

        4. 实时性:抢占式调度器可以保证高优先级任务能够及时响应紧急事件。这对于实时系统和需要快速响应的应用程序非常重要。

        5. 任务挂起:在抢占式调度中,可以随时挂起(暂停)一个任务,以便给更高优先级的任务让路。挂起(暂停)函数为vTaskSuspend(),恢复函数为vTaskResume()

        6. 任务阻塞:一个任务可以由于等待某些条件的发生而被阻塞。当这些条件满足时,RTOS会将其重新置为就绪状态

        7. 中断处理:抢占式调度需要能够在中断上下文中正确地处理任务的切换。

        8. 实时性保证:抢占式调度对于需要在严格的实时约束下工作的系统非常重要,因为它可以确保高优先级任务在预期的时间内得到处理。

总结:

  1. 高优先级任务,优先执行;
  2. 高优先级任务不停止,低优先级任务无法执行;
  3. 被抢占的任务将会进入就绪态。

2.2 时间片调度

优点适用于多个任务优先级相近的场景,可以避免某个任务长时间占用CPU。
缺点会引入一定的上下文切换开销。

        1. 时间片段:CPU的执行时间被划分成固定长度的时间片段。每个时间片段可以是几毫秒或者更短的时间,具体取决于系统的配置。

        2. 任务优先级:每个任务都被分配一个优先级。在一个时间片段内,具有相同优先级的任务会依次轮流执行。

        3. 抢占:当一个时间片段结束时,RTOS会暂停当前执行的任务,并将CPU的控制权转交给具有相同优先级的下一个任务。

        4. 上下文切换:在每个时间片段结束时,RTOS会进行上下文切换,将当前任务的状态保存起来,并加载下一个任务的状态,以便其可以继续执行。

        5. 公平分配CPU时间:时间片调度确保了每个任务在一定时间段内都有机会执行,从而实现了相对公平的CPU时间分配。

        6. 避免任务长时间占用CPU:时间片调度可以防止某个任务长时间占用CPU,从而保证了其他任务也有机会执行。

        7. 适用于优先级相近的任务:时间片调度特别适用于具有相近优先级的任务集,因为它可以确保它们在相对公平的条件下执行。

        8. 降低实时性:相比于抢占式调度,时间片调度可能会引入一定的上下文切换开销,从而降低了系统的实时性。

总结:

  1. 同等优先级任务,轮流执行,时间片流转;
  2. 一个时间片大小,取决为滴答定时器中断周期;
  3. 注意没有用完的时间片不会再使用,下次任务Task3得到执行,还是按照一个时间片的时钟节拍运行。

2.3 协作式调度

        1. 任务自主控制:在协作式调度中,任务负责自己的执行时间任务在需要让出CPU时,会主动调用RTOS提供的让出控制权的函数

        2. 没有明确的任务优先级:协作式调度中通常没有明确的任务优先级概念。所有的任务被视为平等,没有任务可以强制其他任务停止执行。

        3. 低上下文切换开销:相比抢占式调度,协作式调度通常具有更低的上下文切换开销,因为任务只有在愿意让出CPU时才会发生切换

        4. 任务合作:任务之间需要合作以确保系统的正常运行。如果一个任务长时间占用CPU,其他任务可能会受到影响。

        5. 适用于资源受限的系统:协作式调度适用于资源有限的嵌入式系统,因为它减少了抢占式调度中的上下文切换开销。

        6. 可能导致响应性降低:如果一个任务不合作,即使有更高优先级的任务需要执行,也可能导致响应性降低,因为任务不会主动让出CPU。

        7. 任务挂起和任务阻塞:虽然没有抢占,但任务仍然可以被挂起(暂停)或者阻塞,等待某些条件的发生。

3、任务调度案例分析

3.1 实验需求

创建 4 个任务:taskLED1,taskLED2,taskKEY1,taskKEY2,任务要求如下:

taskLED1:间隔 500ms 闪烁 LED1;

taskLED2:间隔 1000ms 闪烁 LED2;

taskKEY1:如果 taskLED1 存在,则按下 KEY1 后删除 taskLED1 ,否则创建 taskLED1 ;

taskKEY2:如果 taskLED2 正常运行,则按下 KEY2 后挂起 taskLED2 ,否则恢复 taskLED2。

3.2 CubeMX配置

查看原理图配置按键跟LED灯引脚

这里已经将FreeRTOS移植到STM32F103C8T6,具体操作流程看前面的文章。

串口配置

创建任务

点击add即可添加任务并修改参数配置,注意:其中任务的优先级从上往下越来越高,设置成Normal即可,同时Entry Fuction为函数指针,固定格式是Start+函数名字(函数名字首个字母需要大写)

3.3 代码实现

3.3.1 uart.c 重定向printf
#include "stdio.h"
int fputc(int ch,FILE *f)
{unsigned char temp[1] = {ch};HAL_UART_Transmit(&huart1,temp,1,0xffff);return ch;
}

需要打开魔术棒勾上红框内选项实现串口打印

3.3.2 打开freertos.c并添加代码
void StartTaskLED1(void const * argument)
{for(;;){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);osDelay(500);}
}void StartTask02(void const * argument)
{for(;;){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);osDelay(1000);}
}void StartTaskKey1(void const * argument)
{for(;;){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET){osDelay(20);if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET){printf("KEY1被按下!!!\r\n");if(task_LED1Handle == NULL)	//在上面任务创建会返回一个句柄,判断句柄是否为NULL																				{printf("任务1不存在,准备创建任务1\r\n");	//为NULL说明任务1不存在												osThreadDef(task_LED1, StartTask_LED1, osPriorityNormal, 0, 128); //调用上面任务创建函数task_LED1Handle = osThreadCreate(osThread(task_LED1), NULL);if(task_LED1Handle != NULL)	//此时任务1创建成功,句柄不为NULL																			printf("任务1创建完成!\r\n");}else{printf("删除任务1!\r\n");osThreadTerminate(task_LED1Handle);	//调用删除任务函数,参数为任务返回的句柄															task_LED1Handle = NULL;	//手动将句柄置为NULL,否则后面调用到此句柄会有意外					 																}}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET);	//若按键一直处于按下状态则处于死循环,即松手检测									}osDelay(10);}void StartTaskKey2(void const * argument)
{static int flag = 0;	for(;;){if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){osDelay(20); // 延时消抖if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){printf("Key2 被按下\r\n");if(flag == 0){osThreadSuspend(TaskLED2Handle);//调用任务挂起函数printf("任务2被挂起暂停\r\n");flag = 1;}else{osThreadResume(TaskLED2Handle);//调用任务恢复函数printf("任务2重新恢复\r\n");flag = 0;}}while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);}osDelay(10);}
}

上述代码中:

osThreadTerminate()为删除函数,osThreadSuspend()为挂起函数,osThreadResume()为恢复函数。(这些函数与前面所学的不一样,因为他们都是CubeMX的内置函数)

下图为创建任务后各个任务的句柄和CubeMX创建任务函数。

3.3.4 代码现象

按下KEY1任务1删除(LED1保持不变),再次按下任务1创建(LED1闪烁);按下KEY2任务2挂起(LED2保持不变),再次按下任务2恢复(LED2闪烁)。

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

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

相关文章

7 系列 FPGA 产品介绍及选型

目录 Spartan-7 FPGAsArtix-7 FPGAsKintex-7 FPGAsVirtex-7 FPGAsFPGA芯片命名规则DSP资源BRAM资源Transceivers 资源Transceivers 总带宽I/O 个数及带宽参考文档 Spartan-7 FPGAs Artix-7 FPGAs Kintex-7 FPGAs Virtex-7 FPGAs FPGA芯片命名规则 DSP资源 BRAM资源 Transceiver…

day5Qt作业

服务器端 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//准备组件,初始化组件状态this->setFixedSize(800,600);chatwidget new QListWidge…

【Linux】Linux——Centos7安装Tomcat

1.下载Tomcat 安装包 官网地址:Apache Tomcat - Apache Tomcat 9 Software Downloadshttps://tomcat.apache.org/download-90.cgi 2.将下载的安装包上传到 Xftp 上,我是直接放到 usr 下了 3.将安装包解压到 /usr/local/ tar -zxvf apache-tomcat-9.0.8…

Java+SpringBoot+JSP实现在线心理评测与咨询系统

前言介绍 随着互联网技术的高速发展,人们生活的各方面都受到互联网技术的影响。现在人们可以通过互联网技术就能实现不出家门就可以通过网络进行系统管理,交易等,而且过程简单、快捷。同样的,在人们的工作生活中,也就…

249 基于matlab的MED、OMEDA、MOMEDA、MCKD信号处理方法

基于matlab的MED、OMEDA、MOMEDA、MCKD信号处理方法。最小熵反褶积(MED),最优最小熵反卷积调整卷积 (OMEDA),多点最优最小熵解卷积调整(Multipoint Optimal Minimum Entropy Deconvolution Adjusted,MOMEDA),最大相关峭…

Neuralink首个脑机接口患者:打游戏、搞研究两不误,重获自主能力

今年1月28日,Neuralink首次将侵入式脑机接口植入人类患者Noland Arbaugh的大脑。100天后,这家由埃隆马斯克创立的公司公布了最新的进展。从Neuralink的更新中我们可以看到,Arbaugh的恢复情况超出预期,他的用户体验也非常积极。 原…

Android 按钮Button点击音效

一、新建工程 编译运行&#xff0c;确保工程无误&#xff0c;这里不过多赘述。 二、UI布局 添加两个播放音效Button <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"…

芋道系统springcloud模块启动报错,枚举类不能为空

问题描述&#xff1a; Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2024-05-10 15:50:15.756 | ERROR 9120 | main [TID: N/A] o.s.b.d.LoggingFailureAnalysisReporter | ************************…

腾讯云coding代码托管平台配置问题公钥拉取失败提示 Permission denied(publickey)

前言 最近在学校有个课设多人开发一个游戏&#xff0c;要团队协作&#xff0c;选用了腾讯云的coding作为代码管理仓库&#xff0c;但在配置的时候遇到了一些问题&#xff0c;相比于github&#xff0c;发现腾讯的coding更难用&#xff0c;&#xff0c;&#xff0c;这里记录一下…

【漫画版】指挥官的排序战术:快速排序算法解密

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任字节跳动数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python&#xff0c;欢迎探讨交流 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题…

stm32单片机学习路线

第一步 编程及硬件基础知识 1.掌握C语言基础 作为STM32的主要编程语言&#xff0c;C语言的基础知识是必不可少的。建议通过书籍、在线课程或者教学视频系统地学习C语言的基础知识&#xff0c;包括语法、数据类型、函数、指针等。 2.了解电子电路基础 对于单片机开发来说&…

面向对象 03:类与对象的创建、初始化和使用,通过 new 关键字调用构造方法,以及创建对象过程的内存分析

一、前言 记录时间 [2024-05-10] 系列文章简摘&#xff1a; Java 笔记 01&#xff1a;Java 概述&#xff0c;MarkDown 常用语法整理 Java 笔记 11&#xff1a;Java 方法相关内容&#xff0c;方法的设计原则&#xff0c;以及方法的定义和调用 面向对象 01&#xff1a;Java 面向对…

ESP32引脚入门指南(四):从理论到实践(PWM)

引言 ESP32 作为物联网领域的明星微控制器&#xff0c;除了强大的Wi-Fi和蓝牙功能&#xff0c;还内置了丰富的外设资源&#xff0c;其中就包括高级的PWM&#xff08;脉冲宽度调制&#xff09;功能。本文将深入探讨ESP32的PWM引脚&#xff0c;解析其工作原理&#xff0c;并通过…

2024年数维杯B题完整代码和思路论文讲解与分析

2024数维杯数学建模完整代码和成品论文已更新&#xff0c;获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/bgic2nbxs2h41pvt?singleDoc# 2024数维杯数学建模B题45页论文和代码已完成&#xff0c;代码为全部问题的代码 论文包括摘要、问题重述、问题分析、模型假设、…

G2 - 人脸图像生成(DCGAN)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 理论知识DCGAN原理 模型结构逻辑结构物理结构 模型实现前期准备1. 导入第三方库2. 修改随机种子(相同的随机种子&#xff0c;第i次随机的结果是固定的)3.…

Cocos creator实现《战机长空》关卡本地存储功能

Cocos creator实现《战机长空》关卡本地存储功能 Cocos creator在开放小游戏过程中&#xff0c;经常会出现设置关卡&#xff0c;这里记录一下关卡数据本地存储功能。 一、关卡设置数据 假如我们有关卡数据如下&#xff0c; let settings [ { level: 1, // 第1关 score: 0,…

SAM轻量化应用Auto-SAM、Group-Mix SAM、RAP-SAM、STLM

1. Auto SAM&#xff08;Auto-Prompting SAM for Mobile Friendly 3D Medical Image Segmentation&#xff09; 1.1 面临问题 医学背景&#xff1a; &#xff08;1&#xff09;与自然图像相比&#xff0c;医学图像的尺寸更小&#xff0c;形状不规则&#xff0c;对比度更低。&…

window10设置静态IP

右键桌面网络图标 点击属性 点击要查看的网络 点击详细信息 获得网络连接详细信息 右键WiFi符号 或者其他方式进入网络与internet中心 点击 WLAN 点击属性 点击编辑&#xff08;点击一个即可&#xff09; 选择手动将刚才的信息方进入即可 完成

多模态中的“单流模型”和“双流模型”

多模态预训练模型按照模型结构可以分为单流和双流两种结构。 单流是指图片和文本在embedding之后就融合在一起进入后续的transformer层。【先将信息fusion&#xff0c;然后再用一个model处理】双流是指文本和图片单独享有自己的transformer层&#xff0c;只在最后做轻量的融合…

VM虚拟机安装调试(步骤如下图)

VM虚拟机安装调试 随着一顿安装操作&#xff0c;还有enter键敲下&#xff0c;出现如下界面。