快速入门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的基础上可以管理多个非连续区域

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

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

相关文章

Cocos制作抖音小游戏接入侧边栏复访接口实例

本篇文章主要讲解,使用cocos接入抖音小游戏侧边栏接口的实例教程。 日期:2024年7月1日 作者:任聪聪 教程实例:https://download.csdn.net/download/hj960511/89509196 下载后可直接导入运行 上传游戏后抖音预审不通过 注意&#x…

98 - IDEA远程调试服务器Java程序

Java 提供了一套标准的调试协议(JDWP - Java Debug Wire Protocol),允许调试器(IDE)与被调试程序(应用)之间进行通信。 1.服务器特定命令启动程序 在服务器上以以下命令启动Java程序 java -a…

南京林业大学点云相关团队论文

【1】Chen Dong, Wan Lincheng, Hu Fan, Li Jing, Chen Yanming, Shen Yueqian*, Peethambaran Jiju, 2024. Semantic-aware room-level indoor modeling from point clouds, International Journal of Applied Earth Observation and Geoinformation, 2024, 127, 103685. 语义…

【Android】【Binder】cpp 如何监听service死亡状态

前言 最近有个需求&#xff0c;需要在cpp bin中监听phone 进程异常死亡的状态。 代码 test.cpp #define LOG_TAG "BINDER_DEATH"#include <binder/IServiceManager.h> #include <binder/Binder.h> #include <binder/Parcel.h> #include <an…

人事系统不知道怎么选?这份国内外EHR系统对比收藏好了!(2000字干货)

随着信息化、数字化的发展&#xff0c;应用于企业运营的管理软件产品也越来越多。判断一个产品是否好用&#xff0c;首先应明确该产品是否能真正解决自身企业管理上的难点和痛点&#xff0c;人事系统产品理念从企业管理痛点中来&#xff0c;应用到服务企业管理中去&#xff0c;…

什么是脏读、幻读、不可重复读

数据库事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作&#xff0c;这些操作要么全部成功执行&#xff0c;要么全部失败回滚&#xff0c;以保持数据库的一致性和完整性。在多线程或多用户同时操作时&#xff0c;难免会出现错乱与冲突&#xff0c;这就需要引入事务的…

软考高级-系统分析师知识点100条速记!

宝子们&#xff01;上半年软考已经结束一段时间了&#xff0c;准备备考下半年软考高级-系统分析师的小伙伴可以开始准备了&#xff0c;毕竟高级科目的难度可是不低的&#xff0c;相信参加过上半年系分的小伙伴深有体会。 这里给大家整理了100条系分知识点&#xff0c;涵盖全书9…

0050__重叠I/O模型

https://blog.51cto.com/u_11146845/6240720

力扣第220题“存在重复元素 III”

在本篇文章中&#xff0c;我们将详细解读力扣第220题“存在重复元素 III”。通过学习本篇文章&#xff0c;读者将掌握如何使用桶排序和滑动窗口来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述…

面试官:你了解git cherry-pick吗

事情要从一次不规范的代码开发开始说起 背景故事 时间 2024年某个风平浪静的周五晚上 地点 中国&#xff0c;北京&#xff0c;西二旗&#xff0c;某互联网大厂会议室 人物 小杰&#xff0c;小A&#xff0c;小B&#xff0c;老K 对话 老K&#xff1a;昨天提交的代码被测试打回来…

[ROS 系列学习教程] 建模与仿真 - 使用 ros_control 控制差速轮式机器人

ROS 系列学习教程(总目录) 本文目录 一、差速轮式机器人二、差速驱动机器人运动学模型三、对外接口3.1 输入接口3.2 输出接口 四、控制器参数五、配置控制器参数六、编写硬件抽象接口七、控制机器人移动八、源码 ros_control 提供了多种控制器&#xff0c;其中 diff_drive_cont…

社科数据整理汇总 - 2

搜索指南&#xff1a;CtrlF 根据关键字搜索&#xff0c;点击标题可直达下载 搜索指南&#xff1a;CtrlF 根据关键字搜索&#xff0c;点击标题可直达下载 搜索指南&#xff1a;CtrlF 根据关键字搜索&#xff0c;点击标题可直达下载 2011-2022年 最新全国省、市、县北京大学数字…

方法的用法

一.简介 目前为止我给出的所有的案例都是将代码放在main方法中&#xff0c;就会产生一些问题&#xff1a; 代码冗长&#xff0c;不利于维护变量过多&#xff0c;想不出那么多的变量名没有重用性 那么该如何解决呢&#xff1f; 我们可以编写功能性的代码块&#xff0c;来被ma…

FormMaking表单设计器V3.8发布,数据表格上线,支持多选、多级表头、列模板自定义、操作列、分页等设置

介绍 FormMaking 是基于Vue的可视化表单设计器&#xff0c;赋能企业实现可视化低代码开发模式&#xff1b;帮助开发者从传统枯燥的表单代码中解放出来&#xff0c;更多关注业务&#xff0c;快速提高效率&#xff0c;节省研发成本。 目前已经在OA系统、考试系统、报表系统、流程…

MyBatis-plus这么好用,不允许还有人不会

你好呀&#xff0c;我是 javapub. 做 Java 的同学都会用到的三件套&#xff0c;Spring、SpringMV、MyBatis。但是由于使用起来配置较多&#xff0c;依赖冲突频发。所有&#xff0c;各路大佬又在这上边做了包装&#xff0c;像我们常用的 SpringBoot、MyBatisPlus。 基于当前要…

报错:RuntimeError_ cuDNN error_ CUDNN_STATUS_EXECUTION_FAILED

原因&#xff1a;pytorch与cuda版本不对 也有可能是内存空间不足&#xff0c;可以更改虚拟空间大小&#xff0c;参考&#xff1a;解决电脑内存不足问题&#xff1a;Win10虚拟内存设置指南

C语言的数据结构:图的操作

&#x1f6fa;图的遍历&#xff1a; 注意&#xff1a;在遍历的过程中&#xff0c;可能会出现 回路 ( 已经访问过的节点还要重新访问一次 ) \color{orange}回路(已经访问过的节点还要重新访问一次) 回路(已经访问过的节点还要重新访问一次). 当从A开始访问时&#xff0c;先访问…

heic格式转化jpg,手把手教你将heic转换成jpg【办公必备】

一、什么是heic heic格式是一种高效的图片格式&#xff0c;它可以在较小的文件大小下提供高质量的图片。 二、如何打开heic 然而&#xff0c;这种图片因其格式的特殊性&#xff0c;在实际应用中仍存在一些问题&#xff1a;压缩效果可能不够理想&#xff0c;一些老旧的软件和设…

[AIGC] HashMap的扩容与缩容:动态调整容量以提高性能

HashMap是Java中常用的数据结构之一&#xff0c;而其性能的优劣与其容量的选择息息相关。本文将详细介绍HashMap的扩容与缩容机制&#xff0c;以及如何动态调整容量以提高性能。 文章目录 一、初始容量和负载因子二、扩容操作三、扩容触发条件四、为什么要扩容&#xff1f;五、…

ubuntu 默认的PATH配置

ubuntu 默认的PATH配置 在Ubuntu系统中&#xff0c;PATH环境变量是非常关键的&#xff0c;因为它定义了操作系统在接收到用户输入命令时&#xff0c;搜索可执行文件的目录顺序。这个变量的配置决定了哪些命令可以被系统全局识别和执行。 默认的PATH配置 Ubuntu的默认PATH环境…