浅谈FreeRTOS任务启动与切换流程

2023-05-16

一个轻量级操作系统最核心的地方就在于任务的执行与切换,像FreeRTOS和ucOSⅢ在任务启动与切换方面都差不多,本文主要从枝干而省去了所有细枝末节让你最快的了解操作系统的任务创建与切换。
以正点原子FreeRTOS移植实验代码为例,该代码主要移植了FreeRTOS操作系统,并创建了4个任务,开始任务、LED闪烁1、LED闪烁2、浮点运算。
1.先从.s启动文件说起
启动文件里面有三个中断是操作系统必要的:
在这里插入图片描述
即SVC_Handler,PendSV_Handler,SysTick_Handler。其中:SVC是用于触发一个PendSV异常来进行一个上下文切换,具体切换过程在PendSV_Handler里完成,SysTick_Handler则是为操作系统提供一个时基,进行一系列操作比如延时时切换任务等。
简单点来说:
SVC_Handler是用于启动第一个任务的中断;
PendSV_Handler是用于每次任务切换中断;
SysTick_Handler是一个定时器,比如一个任务运行3s,这3s就是用这个定时器来计时得到的。
至于为什么这些操作要放在这几个中断内进行,这是因为CM3内核有两种模式:用户和特权,模式不同,权限不同,有些操作需要在特权模式下进行。
具体的代码分析放在后面,现在只了解存在这三个中断。(想了解的可以搜索:CM3的两种模式,两种权限,以及两个指针MSP与PSP,中断与异常)
接下来直接进入到main函数
在这里插入图片描述
在main里面关于操作系统主要存在于三个函数内:delay_init,xTaskCreate,vTaskStartScheduler
其中delay_init中主要开启了SysTick中断:

在这里插入图片描述
然后xTaskCreate是创建函数任务,里面主要操作是为任务申请堆栈空间
在这里插入图片描述
其中分为两种情况:堆栈向上和向下生长两种情况,不做具体讨论。
在为任务申请完空间之后,还有很重要的两个操作:
在这里插入图片描述
填充任务控制块信息和把新创建的任务加入就绪列表。
其中填充任务控制块中比较重要的是:
1获取栈顶地址pxTopOfStack
在这里插入图片描述
protSTACK_GROWTH<0即栈为向下生长,栈顶在高地址,然后需要8字节对齐。
可以看出来pxTopOfStack = 为任务申请的堆栈(数组)首地址+堆栈(数组)大小-1
2填充堆栈区域
在这里插入图片描述
上面的函数即为填充堆栈:
在这里插入图片描述
在这里插入图片描述

至此任务初始化完成。简单来说,任务创建过程就是:

  1. 申请内存
  2. 填充内存
    至于为什么要这么填充内存,其实和取用的时候有关,后面会详细解释。
    接下来就是开始任务调度:
    在这里插入图片描述
    在开启任务调度里面比较重要的是:
    1创建了空闲函数
    2开启任务切换
    在这里插入图片描述
    在这里插入图片描述
    xPortStartScheduler()是开启任务调度,里面除了设置相关内容,最重要的函数如下:
    在这里插入图片描述

即开始第一个任务。
在这里插入图片描述

该函数主要两个作用:

  1. 复位MSP值(MSP存在向量表的起始地址,而向量表起始地址存在SCB_VTO寄存器里(地址:0xE000ED08))
  2. 触发SVC
    SVC的内容如下:
    在这里插入图片描述

该函数主要内容:
8字节对齐
加载pxCurrentTCB(任务控制块,存储每个任务的相关信息)的地址到R3
加载pxCurrentTCB的地址里面的内容到R1
因为pxCurrentTCB的地址里面的内容还是一个地址,所以又加载这个地址里面的内容到R0
R0=pxCurrentTCB首地址内容即栈顶地址,pxCurrentTCB是一个结构体,结构体第一个成员为任务控制块栈顶地址
在这里插入图片描述

所以现在R0=栈顶地址,然后以R0为基址,向高地址++,把地址内的内容依次加载到R4、R5、R6、R7、R8、R9、R10、R11、R14等寄存器
然后把R0此时的地址赋给psp
然后R0=0
basepri=R0
然后用BX指令,把以psp为基址,向高地址++,里面的的内容依次加载到R0、R1、R2、R3、R12、R14、R15、xPSR寄存器内
从这里就可以理解了初始化任务堆栈时,为什么要按顺序填充内存,因为取的时候是按顺序取的。
然后任务的切换是在滴答定时器中断内进行的:
在这里插入图片描述

可以看到里面就一个函数:
在这里插入图片描述

函数里面最重要的是通过设置相应寄存器触发了PendSV中断。
PendSV里面的内容如下:
在这里插入图片描述

主要内容:

  • 把当前任务运行现场保存在当前任务的任务堆栈内
  • 把下个要运行的任务的任务堆栈里面的内容加载到寄存器内
    (s16~s31是开启专门运算浮点的模块时,需要用到的寄存器)。

其实上面两条,1和任务刚初始化时做的一样,只不过任务初始化时是初始化为0,而现在是把当前寄存器内值存起来,保存的位置都一样。2和启动第一个任务一样,把任务堆栈内的内容一一对应加载到对应寄存器内。
至此,操作系统最基本的任务流程就完成了。
总结一下
一. 开启系统滴答定时器
二. 为任务分配运行空间,把任务启动时每个寄存器里面的值按规定好的顺序存在任务分配的运行空间里
三. 触发SVC,开始第一个任务,即把第一个任务运行空间里面的存的寄存器的值按顺序加载到寄存器里
四. 系统滴答定时器中断触发,把现在寄存器内的所有值存进当前任务的运行空间里,加载下个要运行的任务运行空间里面的值到寄存器里。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈FreeRTOS任务启动与切换流程 的相关文章

  • FreeRTOS系列

    1 多任务系统 1 1 前后台系统 单片机裸机开发时 一般都是在main函数里面用while 1 做一个大循环来完成所有的处理 循环中调用相应的函数完成所需的处理 有时也需要在中断中完成一些处理 相对于多任务系统而言 这就是单人单任务系统也
  • 详解FreeRTOS中的软件定时器

    软件定时器用于让某个任务定时执行 或者周期性执行 比如设定某个时间后执行某个函数 或者每隔一段时间执行某个函数 由软件定时器执行的函数称为软件定时器的回调函数 参考资料 Mastering the FreeRTOS Real Time Ke
  • FreeRTOS config开始的宏

    FreeRTOSConfig h系统配置文件中可以自定义 FreeRTOS h中定义默认值 configAPPLICATION ALLOCATED HEAP 默认情况下FreeRTOS的堆内存是由编译器来分配的 将宏configAPPLIC
  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

    目录 一 简介 1 1 开发环境 1 2 摘要 二 STM32CubeIDE配置 三 创建定时器 3 1 头文件声明 3 2 工程文件定义 3 3 创建定时器 3 4 开启 复位 和关闭定时器 四 定时器回调函数 一 简介 1 1 开发环境
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • FreeRTOS简述和移植文档

    FreeRTOS简述和移植文档 文章目录 FreeRTOS简述和移植文档 1 前言 2 FreeRTOS简述 1 概述 2 实现 3 主要特色 4 支持平台 3 移植FreeRTOS 4 最后 1 前言 目前由于IOT的飞速发展 针对单片机
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS记录(九、一个裸机工程转FreeRTOS的实例)

    记录一下一个实际项目由裸机程序改成FreeRTOS 以前产品的平台还是C8051单片机上面的程序 硬件平台改成了STM32L051 同时使用STM32CubeMX生成的工程 使用FreeRTOS系统 EEPROM数据存储读取函数修改更新 2
  • 【FreeRTOS(三)】任务状态

    文章目录 任务状态 任务挂起 vTaskSuspend 取消任务挂起 vTaskResume 挂起任务调度器 vTaskSuspendAll 取消挂起任务调度器 xTaskResumeAll 代码示例 任务挂起 取消任务挂起 代码示例 挂起
  • FreeRTOS之软件定时器

    FreeRTOS之软件定时器 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 include sys h include delay h include usart h include led h in
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 啊哈C的简单使用

    打开啊哈C 新建一个程序输出hello world include
  • FreeRTOS死机原因

    1 中断回调函数中没有使用中断级API xxFromISR 函数 xSemaphoreGiveFromISR uart busy HighterTask 正确 xSemaphoreGive uart busy 错误 2 比configMAX
  • [FreeRTOS入门学习笔记]定时器

    定时器的使用步骤 1 定义一个handle xTimerCreate创建 2 启动定时器 在Task1中调用 通过队列通知守护任务来执行定时器任务 要再config头文件中定义守护任务相关配置 虽然定时器是在task1中启动 但是定时器的任
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥

随机推荐

  • 切换JDK版本运行java命令时报Error: could not open xxx解决方法

    安装了jdk8和jdk11两个版本 xff0c 并配置好环境变量后 切换jdk8没有问题 xff0c 切换jdk11时输入java version检查版本出现了如下图片问题 xff1b 解决方案1 xff1a 将环境变量path中 JAVA
  • 阿里云服务器ubuntu18.04安装可视化界面

    这里写目录标题 一 远程连接ubuntu二 安装可视化界面三 安装过程中的问题 一 远程连接ubuntu 输入root密码即可 xff08 这个为实例密码 xff09 二 安装可视化界面 依次输入以下shell命令 apt span cla
  • 奇偶检验等N、O、E、M、S 五种串口检验位类型

    一 检验位 在串行通讯所发送数据的最后一位 xff0c 用来粗略的检验数据在传输过程中是否有出错 二 检验位的五种类型 1 N xff08 None 没有 xff09 无校验 不加校验位 xff0c 可以少传输一位数据 2 O xff08
  • Onvif登录海康、大华摄像机(IPC)提示权鉴失败的问题解决

    最近用我们的Onvif设备发现客户端测试 xff0c 发现连接某些摄像机Onvif获取不到设备信息 xff0c 提示401权鉴失败 确认用户名和密码都没错的情况下 xff0c 都还是失败 xff0c 软件提示信息截图如下 xff1a 我们测
  • 反解析Android APK

    重命名APK为zip 并解压到当前文件中 下载dex解析工具dex2jar link https github com pxb1988 dex2jar releases tag v2 2 SNAPSHOT 2021 10 31 解析文件命令
  • 大数加法越界处理

    大数越界处理 当数据很大时 xff0c 求中点的方法 i 43 j 2的结果有可能会超出 int 类型的取值范围 在此情况下 xff0c 我们需要换一种计算中点的写法 i 43 j 有可能超出 int 的取值范围 int m 61 i 43
  • idea使用断言

    测试程序 public class TestAssert public static void main String args String s1 61 null assert s1 61 null 默认assert不起作用 需开启 ve
  • 2018年面试总结 -- 多线程很重要,多总结很重要

    2018年面试总结 先后面试了Android Linux C C 43 43 QT 得到的结论有以一下几条 xff1a 1 多线程作为一个高级话题太重要了 几乎每种开发环境下都会问到 xff0c 无论是Android还是QT xff1b 2
  • 平常使用的小问题【Windows11开启不了热点,开启热点后连不上去】

    故障现象 xff1a xff08 1 xff09 连接设备一直显示obtaining ip address xff08 2 xff09 电脑没有显示连接的设备 解决措施 xff1a xff08 1 xff09 先转到设置 xff08 2 x
  • IOException: No such file or directory 问题解决

    文章目录 问题描述 xff1a 注册权限动态申请权限总结 xff1a 问题描述 xff1a Android开发 xff0c 在访问文件夹创建文件的时候 xff0c 报错IOException No such file or director
  • 2020(春)工程伦理MOOC期末考试答案

    单选题 多选题 判断题
  • Git中Fork使用

    GitLab或者GitHub中的Fork可以理解为一个物理副本 xff0c 用来管理代码的一种手段 在参与开源项目代码贡献时 xff0c 通常不会直接获得源代码仓库的Developer权限 这点和一般公司开发不太一样 xff0c 公司一般都
  • 在OK6410上运行QT程序找不到libQtGui.so.4的解决

    想在OK6410上运行自己经过交叉编译的QT程序 xff0c OK6410上烧写的是光盘所带的Linux系统 xff0c 运行程序时出现以下现象 xff1a qt server error while loading shared libr
  • Docker的安装

    这篇文章原文是我2016年10月份写的 xff0c 当时在研究docker xff0c 上周六不经意翻了出来 xff0c 由于3月换工作 xff0c 新环境比较忙 xff0c 没时间写些东西 xff0c 所以先把之前写的东西放一下 xff0
  • CRAZEPONY飞控学习(一)

    在不久前曾研究过最近最为流行的开源飞控Pixhawk的源代码 xff0c 但是由于在这之前没有接触过操作系统这个概念 xff0c 在不知道代码执行流程的情况下看了几个星期的时间 xff0c 脑子里还是一团乱 xff0c 所以决定还是从裸机开
  • PHP常用的设计模式

    php常用的设计模式 xff1a 1 单例模式 xff08 构造方法私有化 xff0c 对外提供实例化对象的静态调用方法 xff09 class Site span class token punctuation span public s
  • 003.多线程-主线程、守护线程、用户线程的区别

    对于线程的分类 xff0c 我们可以简单划分为 xff1a 主线程 xff08 每个进程只有一个主线程 xff09 子线程 主线程 xff1a main方法 子线程 xff1a 非主线程皆是子线程 子线程中可以简单划分为 xff1a 守护线
  • Ubuntu中在当前目录下打开终端

    在Ubuntu中 xff0c 打开终端可以通过Ctrl 43 Alt 43 T来打开 xff0c 但其打开的是 下的 xff0c 如果进入指定的目录 xff0c 便需要通过cd命令来进行切换 xff0c 故本文提供一个可以通过鼠标右键来在当
  • C语言经典面试题100道(校对详解版)

    题目非本人整理 xff0c 转载于https blog csdn net qq 42613510 article details 81225935 做了校对与详解 xff0c 方便大家参考 最后编程答案自己做的 xff0c 还没写完 xff
  • 浅谈FreeRTOS任务启动与切换流程

    一个轻量级操作系统最核心的地方就在于任务的执行与切换 xff0c 像FreeRTOS和ucOS 在任务启动与切换方面都差不多 xff0c 本文主要从枝干而省去了所有细枝末节让你最快的了解操作系统的任务创建与切换 以正点原子FreeRTOS移