Freertos学习

一、概念

实时操作系统,要求一个高的实时性,就不是像在一个死循环中放俩函数了。而是创建俩任务,也叫做俩进程,高速的轮流执行,提高实时性。

堆栈的申请是任务的基础。

二、创建任务

创建任务又两种方式,

第一种是动态创建任务,使用

BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,

                       const char * const pcName,

                       const configSTACK_DEPTH_TYPE usStackDepth,

                       void *pvParameters,

                       UBaseType_t uxPriority,

                       TaskHandle_t * const pxCreatedTask)

在动态创建任务的时候,指定好任务栈的大小后,系统使用函数xTaskCreate去为任务自动申请空间

第二种是静态创建

TaskHandle_t xTaskCreateStatic(TaskFunction_t pxTaskCode,

                               const char *const pcName,

                               const configSTACK_DEPTH_TYPE ulStackDepth,

                               void *const pvParameters,

                               UBaseType_t uxPriority,

                               StackType_t *const puxStackBuffer,

                               StaticTask_t *const pxTaskBuffer)

静态为任务申请空间,空间地址要手动申请,定义一个数组,传入数组头指针就算申请了空间

三、任务优先级

1、调度机制

优先级和时间片是两个概念,平级才有时间片。平级的时候用滴答时间时间片进行任务轮转,只有不同级别的时候才用任务优先级。

优先执行高优先级任务,要是高优先级的任务没有放弃任务权限,低优先级的任务得不到执行。

2、删除任务

使用下面的函数,参数是任务的句柄,TaskHandle_t xTask,删除哪个任务就把哪个人物的句柄放进去。

void vTaskDelete(TaskHandle_t xTask)//这是在任务一中删除任务2,需要加任务句柄,他杀所用

 vTaskDelete(TNULL)//在自己的任务中删除自己,就可以用参数NULL,自杀所用

四、堆栈大小的管理

 每个申请的任栈空间,都是由头和长度组成。任务栈空间分配的大小,要足够的支撑任务的运行,任务变量运行中和定义的变量大小不能超过,栈申请的空间大小。

那么如何确定一个任务需要多大的栈空间呢

 五、任务管理

1、概念

多任务的交替执行如何实现,不是两个,是多个

任务切换的基础是,滴答tick中断,如果优先级相同的三个任务,只要滴答中断一到,就切换任务。就会产生时钟中断。

一到点,到到时间,就会发生Tick_IST中断,Tick基本上上是1ms,可以进行配置,配置成任何想要的时间。

2、任务状态

 runing :运行状态:在跑着的任务

 ready :准备状态:已经创建的任务,等待运行,可以随时运行,等待runing跑完,就要他们跑 了

blocked:阻塞状态:等待着去执行某个任务,可能某个任务的事情还没做完,又要执行了,比如说通信,一个信号还没发送完,又要发送了,应该就需要阻塞了。

suspended:暂停状态:主动休息了,被动休息了,被刮起了,挂起函数。

阻塞和暂停状态有啥不同呢:阻塞是等待某事情的发生,比如信号没法送完,自己任务中有个延时函数也起到了阻塞作用vTaskDelay(10);,这个任务里面有个中断需要触发,一直没有触发,就阻塞住了,一旦中断来了(延时够了),那这个阻塞的任务又可以进行了。

暂停状态是纯粹的休息,是主动和被动休息,需要运行的任务去重新唤醒这个阻塞的。

四种状态如何转换呢?

有三个任务被创建出来后,三个任务都会在read状态,当启用任务调度器的时候,主管任务调度,拉出来一个优先级高的任务去执行,runing状态,执行后然后执行下一个任务,这个read起来。

也可以挂起一个任务,用任务函数。

转换如下

 内存上,不同的任务放在一个链表上,通过头指针找到任务的头。

创建任务,就是把这个任务放在一个,ready链表中

 挂起任务,把这个任务放在了SUSpended列表中了

 实验运行,讲解四种状态

 几个重要函数:

xTaskGetTickCount()得到当前滴答的个数,发生了几次滴答

vTaskSuspend(xHandleTask3);挂起任务

vTaskResume(xHandleTask3);恢复任务

void Task2Function(void * param)
{
    while (1)
    {
        task1flagrun = 0;
        task2flagrun = 1;
        task3flagrun = 0;
        printf("2");

        vTaskDelay(10);   //延时阻塞的任务2
    }
}

3、两个延时函数

 VTaskDel ay和vTaskDelayUntil

 vTaskDelayUntil这个延时函数有啥不一样的呢,就是用这个延时函数,保持每次任务执行的时间是一致的,不是说一会任务时间长,一会任务时间短。

 vTaskDelayUntil相当于任劳任怨的延时函数,给弄得好好,把任务时间补齐,弄得规规整整的,城墙上的守卫者。

4、空闲任务和钩子函数

空闲任务,就是系统自带的优先级最低的任务函数,在这个优先级最低的任务函数中,要做的是一些清理工作。

可是两个任务互相执行,空闲任务得不到执行的话,内存会 爆炸掉吗?

vTaskDelete(NULL);杀死任务可以清理任务内存,可是能这个杀死只能是别人杀死,别人清理尸体,不能自己清理自己的实体。

面试重点:

 我们可以在空闲任务中实现一些不重要的函数,不重要的东西,比如说清理尸体啥的,就需要钩子函数。就是不破化这个Freertos的源码,去改造空闲函数,用钩子钩住点东西。

使用钩子任务也有一些条件和约束:

 钩子函数永远不能进入阻塞和暂停状态。

使用钩子函数方法:

前面个讲了如何创建任务,现在到了处理任务后事的时候了。

5、任务调度算法

优先级高的任务先执行,优先级低的任务交替执行

1、进入阻塞任务,的方式有好几种,等待任务的执行,任务进入阻塞的方式很重要,比如等待消息,消息阻塞有好几种方式

2、可以配置算法调度,看是否可以抢占,实际任务中要支持抢占

 所谓的抢占,就是高优先级可以打断低优先级任务进行运行

如果抢占不了低优先级任务的话,那低优先级任务没有认出自己的任务的话,低优先级任务就要一直执行了。

 3、同优先级的任务可以交替执行,也可以设置为先到先得

#define configUSE_PREEMPTION        1
#define configUSE_TIME_SLICING      0    //这个设置为0的话,低优先级的,在高优先级进行阻塞后也不进行轮转了,就只是先到先得了。
#define configIDLE_SHOULD_YIELD        1

4、空闲任务需要卑微的让出任务权限

#define configIDLE_SHOULD_YIELD        1

这个配置,配置空闲任务是否礼让别人,空闲任务运行的时候,可以让别人占有自己。

1是礼让,0是不礼让,都是0优先级的时候和其他任务 ,共同差不多的时候。

5、重点总结

调度策略

1、任务是否允许抢占

允许抢占的话,高优先级的任务先进性执行

不允许抢占的话,大家平等,哪个任务执行,就一直执行,除非自己让出执行权限

2、在允许抢占的时候还可以配置是否允许时间片轮转

允许的话,同优先级的任务交替执行

不允许的话,谁先运行谁就一直运行,除非主动让出 CPU和被抢占

3、在允许抢占和时间片轮转的时候,还要设置空闲任务是否会让步

如果让步的话,如果礼让,就空闲任务执行的时间少,用户任务优先执行

如果不礼让,那就会和用户同等级的0等级的的任务进行时间片轮转执行

六、同步、互斥和通信的概念

参考文章:

韦东山freeRTOS系列教程之【第一章】FreeRTOS概述与体验_freertos教程_韦东山的博客-CSDN博客

韦东山freeRTOS快速入门 (100ask.net)//视频教程

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图像分类】理论篇(2)经典卷积神经网络 Lenet~Resenet

目录 1、卷积运算 2、经典卷积神经网络 2.1 Lenet 网络构架 代码实现 2.2 Alexnet 网络构架 代码实现 2.3 VGG VGG16网络构架 代码实现 2.4 ResNet ResNet50网络构架 代码实现 1、卷积运算 在二维卷积运算中,卷积窗口从输入张量的左上角开始&#xff…

【SLAM】ORBSLAM34macOS: ORBSLAM3 Project 4(for) macOS Platform

文章目录 配置ORBSLAM34macOS 版本运行步骤:版本修复问题记录:编译 fix运行 fix 配置 硬件:MacBook Pro Intel CPU 系统:macOS Ventura 13.4.1 ORBSLAM34macOS 版本 https://github.com/phdsky/ORB_SLAM3/tree/macOS 运行步骤&…

File Upload

File Upload 文件上传功能是大部分WEB应用的常用功能,网站允许用户自行上传头像、照片、一些服务类网站需要用户上传证明材料的电子档、电商类网站允许用户上传图片展示商品情况等。然而,看似不起眼的文件上传功能如果没有做好安全防护措施,…

数学建模之“聚类分析”原理详解

一、聚类分析的概念 1、聚类分析(又称群分析)是研究样品(或指标)分类问题的一种多元统计法。 2、主要方法:系统聚类法、有序样品聚类法、动态聚类法、模糊聚类法、图论聚类法、聚类预报法等。这里主要介绍系统聚类法…

【学会动态规划】单词拆分(24)

目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…

【微服务技术一】Eureka、Nacos、Ribbon(配置管理、注册中心、负载均衡)

微服务技术一 技术栈图一、注册中心Eureka概念:搭建EurekaServer服务注册服务发现(消费者对提供者的远程调用) 二、Ribbon负载均衡负载均衡的原理:LoadBalanced负载均衡的策略:IRule懒加载 三、Nacos注册中心Nacos的安…

CG MAGIC分享为什么使用3d Max渲染,呈现白蒙蒙的?

使用3d Max渲染,有小伙伴反映,为什么渲染过程中,max渲染,总是出现白蒙蒙的的效果呢? 渲染出这白白一片是什么原因导致的呢? 想要解决的朋友,点进来,看看CG MAGIC小编整理的解决方法…

208、仿真-51单片机脉搏心率与心电报警Proteus仿真设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、程序源码 资料包括: 需要完整的资料可以点击下面的名片加下我,找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&a…

学习笔记:Opencv实现图像特征提取算法SIFT

2023.8.19 为了在暑假内实现深度学习的进阶学习,特意学习一下传统算法,分享学习心得,记录学习日常 SIFT的百科: SIFT Scale Invariant Feature Transform, 尺度不变特征转换 全网最详细SIFT算法原理实现_ssift算法_Tc.小浩的博客…

python+django+mysql项目实践四(信息修改+用户登陆)

python项目实践 环境说明: Pycharm 开发环境 Django 前端 MySQL 数据库 Navicat 数据库管理 用户信息修改 修改用户信息需要显示原内容,进行修改 通过url传递编号 urls views 修改内容需要用数据库的更新,用update进行更新,用filter进行选择 输入参数多nid,传递要修…

深度学习优化器

1、什么是优化器 优化器用来寻找模型的最优解。 2、常见优化器 2.1. 批量梯度下降法BGD(Batch Gradient Descent) 2.1.1、BGD表示 BGD 采用整个训练集的数据来计算 cost function 对参数的梯度: 假设要学习训练的模型参数为W,代价函数为J(W),…

数组详解

1. 一维数组的创建和初始化 1.1 数组的创建 数组是一组相同类型元素的集合。 数组的创建方式: type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式,用来指定数组的大小 数组创建的实例: //代码1 int a…

OCT介绍和分类

前言:研究方向和OCT有关,为了方便以后回顾,所以整理了OCT相关的一些内容。 OCT介绍和分类 OCT介绍分类时域OCT频域OCT扫频OCT谱域OCT OCT介绍 名称:OCT、光学相干层析成像术、Optical Coherence Tomography。 概念:O…

CSS中的calc()函数有什么作用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS中的calc()函数及其作用⭐ 作用⭐ 示例1. 动态计算宽度:2. 响应式布局:3. 自适应字体大小:4. 计算间距: ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点…

深度学习的“前世今生”

1、“感知机”的诞生 20世纪50年代,人工智能派生出了这样两个学派,分别是“符号学派”及“连接学派”。前者的领军学者有Marvin Minsky及John McCarthy,后者则是由Frank Rosenblatt所领导。 “符号学派”的人相信对机器从头编程&#xff0c…

KeilMDk软仿真设置_STM32F03C8

1、KeilMDK软仿真的价值 (1)在没有硬件的情况下进行程序的编写调试。 (2)避免频繁的下载程序,延长单片机Flash寿命。 2、软仿真配置。 (1)打开Keil工程。 (2)点击“Options for Target ***”,如下图所示。 (3)点击“Debug”。 (4)进行如下配置。 U…

云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM---初步使用(二)

前言: 在前面一篇文章云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM---初始安装(一)_华为cna_晚风_END的博客-CSDN博客 介绍了基于VMware虚拟机里嵌套部署华为云的云计算,不过仅仅是做到了在VRM的web界面添加计算节点…

Java入门必备|有你想知道的代码技巧

前言 本文主要分享记录学习Java时的敲代码大法,一步步与idea这个软件磨合,让它为我们敲代码这条路提供更便捷的帮助(雀食好用哈) 一.psvm 很多刚上手IJ软件,就被main()方法给折服了,这段代码量十分大 当…

C++音乐播放系统

C音乐播放系统 音乐的好处c发出声音乐谱与赫兹对照把歌打到c上 学习c的同学们都知道,c是一个一本正经的编程语言,因该没有人用它来做游戏、做病毒、做…做…做音乐播放系统吧!! 音乐的好处 提升情绪:音乐能够影响我们…

【小梦C嘎嘎——启航篇】vector 以及日常使用的接口介绍

【小梦C嘎嘎——启航篇】vector 日常使用的接口介绍😎 前言🙌vector 是什么?vector 比较常使用的接口 总结撒花💞 😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧&#xff01…