当前位置: 首页 > news >正文

FreeRTOS内部机制学习01(任务创建的细节以及任务调度的内部机制)

文章目录

  • 前言:首先要谢谢韦东山老师的无私奉献,让我学到了很多东西,我做这个笔记是害怕我会忘记,所以就记录了下来,希望对大家有帮助!
  • 关于寄存器
    • CPU内部的寄存器
    • 这些寄存器到底要保存一些什么?
    • 某些寄存器记录的场景
  • FreeRTOS中怎么创建任务
    • 创建任务的函数:
    • 创建任务时函数内部都干了什么?:
  • 任务的调度
    • 任务调度的基本机制
    • 任务调度的核心
    • 再深度一点任务链表调度
    • 任务调度切换做了什么?
    • 关于任务挂起以及休眠期间的行为

前言:首先要谢谢韦东山老师的无私奉献,让我学到了很多东西,我做这个笔记是害怕我会忘记,所以就记录了下来,希望对大家有帮助!

关于寄存器

关于任务的轮换以及中断恢复继续得以原来为止继续运行,一点也离不开寄存器的作用,所以想要了解任务,了解寄存器也是必不可少的!

CPU内部的寄存器

CPU内部有R0、R1、……、R15共16个寄存器
某些寄存器有特殊作用
R13,别名SP,栈寄存器,保存着栈的地址
R14,别名LR,返回地址,保存着函数的返回地址
R15,别名PC,程序计数器,也就是当期程序运行到哪了

这些寄存器到底要保存一些什么?

记录程序运行到了哪里实际上是靠PC寄存器来完成的?PC寄存器的值

函数中一般也会有着函数嵌套的使用,一个函数中还调用了另外一个函数,当这个函数运行完成后,要怎么返回到调用的地址呢?这就要靠LR来记录了!

其他寄存器也有着他们各自要记录的数据,比如R0,R1就专门用来传函数参的!

某些寄存器记录的场景

1、函数调用 2、中断处理 3、任务切换

FreeRTOS中怎么创建任务

创建任务的核心:栈、TCB结构体

创建任务的函数:

在这里插入图片描述
看到这个函数的参数中的栈的大小,我们疑惑该如何合理定义他的大小呢?这个定义的栈的内存又是从哪里来的呢?

创建任务时函数内部都干了什么?:

大小的定义:这个一般取决于我们任务重的局部变量的大小以及函数调用的深度来决定的,我们使用过程中一般都会使用动态分配,所以就不再深究了。
哪里来?
打开一个工程,我们可以从里面的heap2.c文件中看到,里面开辟了一个数组(空闲的内存),这个就是用于各个任务的栈。
在这里插入图片描述

分配好了栈后,这个栈的起始地址就会存在这个任务的TCB结构体里面的pxstack.
再根据起始地址找到PC,得以继续从原来地方继续往下运行,假如给一个任务分配好了,大概样子就会是这样:

假设这个任务被中断了,各个寄存器就会保存好当前的东西,到时候这个任务再次运行的时候就恢复,继续在上次运行到的地方继续运行!
在这里插入图片描述
创建每个任务时,都会给每个任务分配一个结构体(TCB结构体)
在这里插入图片描述
关于结构体(有删减,保留了主要的内容):

在这里插入图片描述

任务的调度

任务调度的基本机制

优先级不同
1、高优先级的任务,优先执行,可以抢占低优先级的任务
2、高优先级的任务不停止,低优先级的任务永远无法执行
3、同等优先级的任务,轮流执行:时间片轮转
状态
运行态:running
就绪态:ready
阻塞:blocked,等待某件事(时间、事件)
暂停:suspend,休息去了
怎么管理?
找到最高优先级的运行态、就绪态任务,运行它
如果大家平级,轮流执行:排队,链表前面的先运行,运行1个tick后乖乖地去链表尾部排队
谁进行调度?
TICK中断!

任务调度的核心

任务的调度的核心就是链表!!!
在每次创建任务时,都会产生一个TCB结构体,上面也有讲,每次创建任务时,里面的操作还会将这个任务的TCB结构体加入到一个链表里面。
在这里插入图片描述
循序渐进,我们可以发现里面定义了很多链表,现在我们就先来了解其中关于任务创建的链表:
在这里插入图片描述
在这里插入图片描述
相信可以从链表的英文名就可以看出,这些链表的命名与任务的状态有关系。自然而然的就知道了其中的奥妙了吧!
创建任务时会把任务的TCB放入到Ready链表中,“就绪了,准备发车!“。

再深度一点任务链表调度

在这里插入图片描述

我们首先创建两个优先级一样的任务,好了,函数就会把他们两个的TCB放入Ready链表里面,那么到底是谁先运行呢?我刚开始以为是随机的,起始不然,程序运行时,内核会逐个的从高优先级往下找,找到高优先级的就先运行
在这里插入图片描述
这里只创建了两个相同优先级的任务,这里先创建的任务1,其次再是任务2,等级都为0,那么Ready链表里面存有它们的TCB,里面会有一个“指针”寻址这位置,创建任务一时,指向任务1,创建任务2时,就指向了2了,所以这里会先找到任务2,运行了任务2再到任务1!(TCB里面有着每个任务的栈的起始地址,再根据起始地址找到PC)

任务调度切换做了什么?

精简四字概括:保留,恢复
在这里插入图片描述

关于任务挂起以及休眠期间的行为

在这里插入图片描述
Delay函数就会做出这样的行为:
在这里插入图片描述
这里delay了五个Tick:
接下来没一个Tick,系统都会去Delay链表里面看看任务的时间有没有到,如果到了,就会将Task3的TCB从Delay链表中移去,重新加入到Reeay链表中!
在这里插入图片描述

http://www.lryc.cn/news/431831.html

相关文章:

  • CANoe突然出现Trace窗口筛选项无法显示的问题
  • Linux日志-sar日志
  • 全国计算机二级考试C语言篇3——选择题
  • Python实现混合蛙跳算法
  • 印度再现超级大片,豪华阵容加顶级特效
  • Git使用经验总结6-删除远端历史记录
  • Linux 下查找运行中的 Java 进程及 .jar 文件位置
  • Openwrt 安装 AX210 无线网卡
  • 在VitePress中进行页面链接:最佳实践与实例
  • Qt/C++百度地图/高德地图/天地图/腾讯地图/谷歌地图/加载绘图工具栏
  • Vue2 与 Vue3 的区别有哪些
  • 加锁造成的线程优先级反转
  • 【日常记录-Java】SpringBoot中使用无返回值的异步方法
  • 【深度学习】多层感知机的从零开始实现与简洁实现
  • 4、Django Admin对自定义的计算字段进行排序
  • rsync搭建全网备份
  • 网络安全售前入门09安全服务——安全加固服务
  • 【Android】GreenDao数据库的使用方式
  • 搜索算法之线性搜索详细解读(附带Java代码解读)
  • Quartz.Net_依赖注入
  • 【系统架构设计师-2011年】综合知识-答案及详解
  • World of Warcraft [CLASSIC][80][Grandel]Sapphire Hive Drone
  • Unity 对接 Android 第三方广告,App 切换到后台后,再次打开时,第三方广告被销毁导致无法触发回调逻辑的问题
  • Kafka Broker处于高负载状态(例如消息处理量大或系统资源不足),无法及时响应消费者的请求
  • 相关二叉树进阶面试题的讲解?看这一篇足矣
  • Nginx部署前端Vue项目的深度解析
  • PHP一站式解决方案高级房产系统小程序源码
  • 轻量级模型解读——EfficientNet系列
  • 深入浅出SRS—RTMP实现
  • 睿赛德科技携手先楫共创RISC-V生态|RT-Thread EtherCAT主从站方案大放异彩