快速入门FreeRTOS心得(正点原子学习版)

对于FreeROTS,我第一反应想到的就是通信里的TDM(时分多址)。不同任务给予分配不同的时间间隔,也就是任务之间在每个timeslot都在来回切换。

这里有重要的一点,就是中断要短小,优先级是自高到底进行打断。

每个任务都是独立且无限循环

while(1){task1();}
while(1){task2();}

每个任务都有自己的堆栈空间,保存寄存器值

1:调度方法

抢占式调度:优先级高大于低,高优先级任务不停止低优先级就不进行。被抢占的任务会进行就绪状态。1-2-3-2-3,1最低被2抢占,2被3抢占阻塞,2已经就绪,回到2执行,3就绪执行3

时间片调度:优先级相同任务,顺序轮回调度。task1-task2-task1-task2,遇到阻塞任务直接跳到下一个任务运行

携程式调度:当前任务一直执行

2:任务状态

就绪:条件准备好了,还没执行

阻塞:因为延时等外部信号量进入阻塞

运行:同一时刻只有1个任务运行

挂起:暂停

在任务创建方面我感受最深的就是以前数据结构学的动态双向循环链表派上了用场,虽然学的时间有些长忘记了很多,但是没事看看源码或者脑图也能会议许多。本质上这些任务的是切换叫上下文切换,任务的创建在内存中。就像任务创建是分配的堆栈空间(内存)。由人工进行内存管理分配叫做静态创建,由freertos自己分配内存就叫做动态创建。

任务创建结束后,迎来了任务切换,涉及到根据优先级来决定任务出场顺序的抢占式和同优先级时分复用的时间片调度。这些任务创建切换跟内存有什么关系呢?

任务由人为创建,内存由操作系统自动申请。任务在执行时由内存中读出并出栈到cpu寄存器中(符合一个先进后出的顺序)或者叫单片机寄存器中(加载现场)。如果遇到了任务调度导致的任务切换或者中断之类的,会将cpu寄存器中保存的内容入栈到相应的任务内存中(保存现场)。所有的任务都会有一个结构体:任务控制块。当然所有任务也会属于任务链表的某一个:比如就绪表、阻塞表、挂起表、运行表,其中只有就绪列表中的任务会根据优先级来进行执行。阻塞就如其名字,任务突然不运行了,停住了,不向下执行了,就阻塞住了。一般会等待某个状态、信号量、延时之类的。我们平时将延时分为死延时和操作系统给出的延时函数,死延时相当于一个任务语句不会涉及到任务阻塞。什么时候会阻塞,比如你执行一个函数,函数需要获取一个信号量,但是该信号量未被释放(别人拿走了),你一定要拿到它,就一直等,然后你就阻塞了。由于任务调度,你会把位置让出来给次优先级就绪任务运行。
在ARM Cortex-M微控制器架构中,MSP(Main Stack Pointer)和PSP(Process Stack Pointer)是两种特殊的寄存器,它们用于管理不同的堆栈:

1. **MSP(Main Stack Pointer)**:
   - MSP是主堆栈指针,用于中断服务例程(ISRs)和系统初始化时的堆栈操作。
   - 当发生中断时,如果优先级更高的中断发生,当前中断服务例程的上下文(包括程序计数器PC、链接寄存器LR、以及一些通用寄存器)将被保存到MSP指向的堆栈中。
   - MSP通常在系统启动时由启动代码设置,并指向一个预定的内存区域。

2. **PSP(Process Stack Pointer)**:
   - PSP是进程堆栈指针,用于用户代码和任务切换。
   - 在多任务操作系统(如FreeRTOS)中,PSP用于保存任务的上下文,当任务被挂起或切换时,其上下文将被保存到PSP指向的堆栈中。
   - PSP可以在任务创建时被设置,并且每个任务可以有自己的PSP,从而拥有独立的堆栈空间。

MSP和PSP的主要区别在于它们的用途和上下文保存机制:

- **用途**:MSP主要用于中断处理,而PSP用于任务切换。
- **上下文保存**:MSP保存中断服务例程的上下文,PSP保存任务的上下文。
- **独立性**:MSP通常是全局的,而PSP可以是任务特定的。

在FreeRTOS中,当创建一个新任务时,会为该任务分配一个堆栈,并设置其PSP。当任务被切换出去时,它的寄存器和堆栈指针状态将被保存在PSP指向的堆栈中。当任务再次被调度执行时,FreeRTOS会从PSP指向的堆栈中恢复任务的状态。

在中断编程中,MSP用于快速保存和恢复当前中断的上下文,以便中断可以快速响应并返回到被中断的任务或另一个中断服务例程。

正确管理MSP和PSP对于确保程序的稳定性和实时性至关重要,特别是在中断密集型或多任务环境中。

任务控制块就是一个大的结构体,包含了很多东西。挂起一般,我目前认为就是人为暂停了,不像阻塞可以自动移除阻塞态进入就绪态,,挂起如果不进行解挂就会一直处于挂起态。

FreeRTOS能够管理 的中断等级经配置中断优先级分组为 抢占4子优先级0后分为0~15个级别,其只能控制5~15这些,越小中断优先级越高。0~4不受控制。任务优先级可以0~31,越大优先级越高。

现在已经用到了两个数据结构:栈和链表。

在队列中,队列分为两个结构,一个是队列结构体成员,另一个就是队列项了。当然一个队列也是个大结构体,队列一般是作为先进先出FIFO的代表。也可以设置为后进先出,队列空的时候读不到东西,要入队。队列满的时候读尾部成员会使其出队,成员数减1.队列可以进行址传递。当然基于队列开发的信号量分为二值信号量、互斥信号量、计数信号量

二值信号量顾名思义就是只有0,1两种形式,0代表有余,1代表信号量被占用了。信号量动态创建的时候是没有释放的,要人为释放才能获取。由于二值信号量这个特点,会造成高优先级任务被阻塞掉,低优先级任务会多执行,会对实时操作系统的优先级造成影响。为了解决这个问题得到互斥信号量,与二值信号量的区别就是,低优先级任务会被提升至与高优先级任务同等优先级,这样就可以解决优先级翻转问题。计数信号量就是在二值的基础上可以人为定义信号量大小。

事件标志组,在裸机里经常会定义一个flag全局变量,用来在按键或者其他位置进行事件判断。而freertos自带一个,不需要我们再去定义。

任务通知,固定在任务结构体内。除了队列,信号量,事件标志组不需要中介进行任务之间通信,属于直接通信。局限性:无法发送信息给ISR,ISR可以发送给任务通知,无法转播给多个任务

不支持阻塞,只能保持一个数据

任务通知可以模拟 信号量,事件标志组

也可以模拟消息 ,可以把传递的消息保存给一个值,类似于队列的功能

软件定时器:任务调度器在创建的时候会有软件定时器任务和空闲任务。软件定时器任务会有一个超时回调函数,其中不能使用可能会导致系统阻塞的函数,比如延时函数。

跟中断的用法差不多,用了(发送队列)就是运行态,不用就休眠。超时就回调处理,所有定时器都在定时器任务中处理。单次执行一次,周期的就一直周期执行。整个过程其实开启超时回调休眠,周期的就是开启 超时回调超时回调,不主动停止就不会休眠。

低功耗模式:本质经过cortex内核__WFI指令进入睡眠模式。空闲任务进入低功耗,其他任务时退出低功耗。如果有更高的功耗需求可以在睡眠之前关闭外设时钟,睡眠结束后打开外设时钟。

内存管理:与栈(Stack)不同,堆内存的分配和释放是由程序员控制的

根据划分的堆的大小(heap)

还有5个不同的内存分配函数,heap1是只能分配不能释放,heap2是在1的基础上能释放,并且能够自适应的获取内存大小。释放的内存不能与相邻内存合并。假如申请一个30的,你的一个块是35,会切掉5个给后面的内存块。而且内存碎片不能合并。heap3是C、库的内存方案,线程安全没有考虑到,heap4在3的基础上可以合并内存碎片,heap5在4的基础上可以管理多个非连续区域

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

204.贪心算法:分发饼干(力扣)

以下来源于代码随想录 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {// 对孩子的胃口进行排序sort(g.begin(), g.end());// 对饼干的尺寸进行排序sort(s.begin(), s.end());int index s.size() - 1; // 从最大的饼…

大数据招商的应用场景及实施路径有哪些?

当下&#xff0c;我国已经进入数字经济与实体经济融合发展的新阶段&#xff0c;数字技术和数字化转型落地日臻成熟&#xff0c;数据要素价值释放深入到了我国各个领域的发展&#xff0c;招商引资也不例外&#xff0c;在传统招商模式效果日渐甚微的大环境下&#xff0c;大数据招…

面试题 4:阐述以下方法 @classmethod, @staticmethod, @property?

欢迎莅临我的博客 &#x1f49d;&#x1f49d;&#x1f49d;&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

数据大小端问题

文章目录 大小端前言函数引用(接下来使用此函数对高低位进行切换)先看截取的对于大小端的定义大小端数据的直观理解[重点] 对uchar数组进行取操作定义一个uint8_t的数组观察起内部内存尝试使用uint32_t 每次区 1、2、3、4byte数据 提升经过上面的介绍一定对大小端有了一定的了解…

2.3 主程序和外部IO交互 (文件映射方式)----IO Server实现

2.3 主程序和外部IO交互 &#xff08;文件映射方式&#xff09;----IO Server C实现 效果显示 1 内存共享概念 基本原理&#xff1a;以页面为单位&#xff0c;将一个普通文件映射到内存中&#xff0c;达到共享内存和节约内存的目的&#xff0c;通常在需要对文件进行频繁读写时…

基于OpenMV识别数字及程序说明

OpenMV简介 OpenMV是一个开源、低成本且功能强大的机器视觉模块。它基于STM32F427CPU&#xff0c;集成了OV7725摄像头芯片&#xff0c;能在小巧的硬件模块上&#xff0c;用C语言高效地实现核心机器视觉算法&#xff0c;并提供了Python编程接口&#xff0c;使得图像处理的复杂度…

【教程】lighttpd配置端口反向代理

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 1、修改配置文件&#xff1a; sudo vim /etc/lighttpd/lighttpd.conf2、先添加mod_proxy&#xff1a; 3、然后添加端口映射&#xff1a; 4、保存&…

2024年07年01日 Redis数据类型以及使用场景

String Hash List Set Sorted Set String&#xff0c;用的最多&#xff0c;对象序列化成json然后存储 1.对象缓存&#xff0c;单值缓存 2.分布式锁 Hash&#xff0c;不怎么用到 1.可缓存经常需要修改值的对象&#xff0c;可单独对对象某个属性进行修改 HMSET user {userI…

Transformation(转换)开发-switch/case组件

一、switch/case组件-条件判断 体育老师要做一件非常重要的事情&#xff1a;判断学生是男孩还是女孩、或者是蜘蛛&#xff0c;然后让他们各自到指定的队伍中 体育老师做的事情&#xff0c;我们同样也会在Kettle中会经常用来。在Kettle中&#xff0c;switch/case组件可以来做类似…

河南特岗教师报名流程及免冠照片电子版制作要求

2024年河南特岗教师招聘季又来啦&#xff01;想要成为孩子们心中的超级英雄吗&#xff1f;想要在教育的田野上播种希望吗&#xff1f;那就不要错过这次机会&#xff0c;今年全省共招聘特岗教师3495名&#xff08;具体岗位设置参见《河南省2024年特岗教师招聘岗位设置》&#xf…

盒子模型(笔记)

盒子模型 盒子模型的属性 padding属性 内边距&#xff1a;盒子的边框到内容的距离 /*每个方向内边距*/padding-top: 20px;padding-left:20px;padding-bottom:20px;padding-right: 20px; /*每个方向内边距的第二种方法*/ /* 顺序依次是上左右下*/padding: 10px 20px 30px 4…

02:vim的使用和权限管控

vim的使用 1、vim基础使用1.1、vim pathname 2、vim高级用法2.1、查找2.2、设置显示行号2.3、快速切换行2.4、 行删除2.5、行复制粘贴 3、权限管理3.1、普通用户和特权用户3.2、文件权限表示 vim是Linux中的一种编辑器&#xff0c;类似于window中的记事本&#xff0c;可以对创建…

TP8/6 更改后台入口地址admin改为myadmin 隐藏真实后台网址

原来www.xxx.com/admin 改后www.xxx.com/myadmin config/app.php // 应用映射&#xff08;自动多应用模式有效&#xff09;app_map > [admintest>admin],

【前端VUE】VUE3第一节—vite创建vue3工程

什么是VUE Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0…

卷积层里的填充和步幅

一、定义 1、对于卷积&#xff0c;我们另一个超参数是核的大小&#xff0c;通常使用的卷积核是33或者55&#xff0c;很少用偶数核 2、填充是为了让输出不变或者变大&#xff0c;是为了在输入不太大&#xff0c;又能使模型足够深的情况下使用 3、填充&#xff1a;在输入周围添…

开源软件开发平台哪家好?

进行数字化转型&#xff0c;离不开低代码技术平台等软件产品的加持与助力。因为它更好操作、更灵活、易维护等优势特点突出&#xff0c;在推动企业实现流程化办公的过程中助力明显&#xff0c;作用大&#xff0c;深得客户喜爱。那么&#xff0c;低代码技术平台、开源软件开发平…

居然这么简单就能实现扫雷游戏!

目录 一.思路 1.成果展示 2.思路 二.具体操作 1.创建"棋盘" 2.初始化雷 3.布置雷 4.打印 5.排除雷 三.代码实现 1.test.c文件 2.thunder.h文件 3.thunder.c文件 Hello&#xff0c;大家好&#xff0c;今天我们来实现扫雷游戏&#xff0c;希望这一篇博客能给带给大家一…

HCIA是什么等级的证书

HCIA是华为认证体系中的初级认证&#xff0c;主要用于表明持有者在某一技术领域达到了工程师级别的能力证明。这种认证主要涉及到ICT(信息技术基础设施与通信)设备的安装、配置、运行以及故障排除等方面。 HCIA证书的作用 HCIA证书是进入IT行业的一个初步资格证书&#xff0c;它…

昇思25天学习打卡营第6天|数据变换 Transforms

学习目标&#xff1a;熟练掌握数据变换操作 熟悉mindspore.dataset.transforms接口 实践掌握常用变换 昇思大模型平台学习心得记录&#xff1a; 一、关于mindspore.dataset.transforms 1.1 变换 mindspore.dataset.transforms.Compose将多个数据增强操作组合使用。 mindspo…

【Java】如果让你设计一个分布式链路跟踪系统?你怎么做?

一、问题解析 分布式链路跟踪服务属于写多读少的服务&#xff0c;是我们线上排查问题的重要支撑。我经历过的一个系统&#xff0c;同时支持着多条业务线&#xff0c;实际用上的服务器有两百台左右&#xff0c;这种量级的系统想排查故障&#xff0c;难度可想而知。 因此&#…