【RTOS】《多任务抢占式调度器》笔记
《多任务抢占式调度器》读书笔记
1、多任务系统
在多任务调度器的作用下,多个任务轮流使用cpu,实现多任务相互独立并发运行的效果,能够充分利用硬件资源,提高cpu效率
2、任务特性
a、动态性
运行态:任务处于占用cpu运行的状态,有且只能有一个处于运行态的任务
就绪态:可运行的任务,等待占用cpu的任务释放cpu
挂起态:由与某些条件不满足而不能运行的任务
b、独立性
任务之间相互独立,不存在相互调用的关系,使得任务在逻辑上是平等的,任务见的通信由规定的变量来传输
c、并发性
由同一cpu轮换运行多个任务,注意任务并不需要运行完了才能去运行其他任务
3、抢占式调度
在就绪态的任务中出现了优先级比当前任务优先级高的任务,便立即剥夺当前任务运行权,把cpu分配给优先级最高的任务,这样cpu总是在执行就绪条件下优先级最高的任务
4、多任务的时间基准
由一个定时器产生固定周期中断充当时间基准
5、任务的挂起与恢复
当高优先级任务需要给低优先级任务让道时,需要将高优先级任务挂起,通过OSDelay设置挂起时间拍数,在时间到来后将被挂起的高优先级再恢复为就绪
定时器中断服务函数中,依次给各个任务延时节拍数减一,一旦某个任务延时结束(节拍数减到0),就将它由挂起态变为就绪态
程序中可设置一始终处于就绪态的最低优先级空闲函数,保证其他函数挂起时cpu有事可做
6、可重入设计
当某一任务正在运行某个公共函数,接着被更高优先级的任务抢占,而这一任务恰好也要调用这一公共函数,那么就极有可能破坏前一个任务在这个函数的数据,因此我们采用可重入设计来规避这种情况
// 电赛延期,进度不能断,继续
可重入函数中所有变量都为局部变量,故在不同任务调用该函数时,对于同一局部变量所分配的存储空间并不相同,所以不会相互干扰
7、互斥调用
除了可重入设计以外,我们还可以采用互斥调用的方法来规避数据的互相破坏;临界资源是公共资源,但不具备被多个线程访问的特性,因此在多任务系统中,我们需要保证共享资源的互斥访问,要实现互斥访问,方法有在访问临界资源的程序(称为临界区)关中断、关调度、互斥信号量、计数信号量等,使得临界区程序执行时不被其他任务打断,使得该任务在访问临界资源时处于独占状态,因此也需要注意,临界区的代码要尽量短,否则将降低cpu响应性能
8、全局变量与局部变量
全局变量存储在公共的数据存储器里,局部变量存储在所属函数的私有栈里,栈,可以引申为客栈,即临时存放数据的地方,栈是一个线性的空间,可以用通过申请一个静态的数组,打造一个人工栈,注意栈的大小要合适
9、任务控制块Task Contrl Block(TCB)
每个任务都有一个任务控制块,用于记录任务执行的环境,一般为一结构体,作为任务与数据的桥梁,找到他就可以找到任务的所有资源,如此,我们的得到了任务的三个要件:程序代码、私有栈、任务控制块
图示:
10、任务的切换
当任务1将cpu让给任务2时,首先,任务1需要做好自己的收尾工作,即将自己的现场数据——PC、寄存器值压入任务堆栈,SP指针存入任务控制块,同时,任务2做好交接工作,将任务堆栈中的PC、寄存器值从堆栈中取出来,将SP指针从任务控制块取出。故本质上,交接工作是取出SP指针,因为任务栈存的PC和寄存器值地址也存在SP指针里
11、任务的创建
创建任务的函数OSTaskCreate()将接收三个参数:任务的入口地址、任务堆栈的首地址和任务的优先级,调用任务创建这一函数后,系统会根据用户给出的参数初始化任务私有栈,并将堆栈指针保存到任务控制块中,在任务就绪表中标记任务为就绪状态。
初始化后的任务私有栈保存着PC、LR以及寄存器值等,一般会按一定顺序,且PC排在易于访问的位置
多任务系统启动后,将运行OSStartHighRdy,这一函数会将第一个运行的任务的SP从TCB中取出,而后由SP依次将cpu的现场恢复,这是这个任务将占有cpu,直到其他任务抢占cpu;OSStartHighRdy只在启动伊始运行一次
12、实现抢占式调度
基于任务优先级的抢占式调度,也就是当最高优先级任务进入就绪状态时,立即抢占正在运行的低优先级任务的cpu资源,为保证cpu总是在执行优先级最高任务,我们需要在任务状态改变后就执行一次对当前执行任务是否为最高优先级任务的判断
任务状态会在什么时候改变呢,一是当高优先级任务因需要某种资源或延时,主动请求挂起,此时处于就绪状态的低优先级任务可以运行,称为任务级的切换;二是当高优先级任务因为时钟节拍的到来或中断处理结束后,内核发现更高优先级任务获得了执行权限(如延时的时钟到时),则在中断后直接切到更高优先级任务执行,这种调度称为中断级的切换
// insert:名词解释:IRQ:Interrupt ReQuest中断请求;ISR:Interrupt ServeR中断服务程序
任务级的切换详见10、11,下面讲讲中断级的切换
与STM32 HAL类似,系统也存在一个统管了系统所有中断的ASM_IRQHandler,用于中断的调度,同时也会指向C函数C_IRQHandler(),在其中判断中断类型,并跳转到对应的中断服务函数,执行服务函数的内容,执行完后,将推出中断,执行OSInitExit,但,根据中断嵌套的原则,并不会立即返回先前的任务,而是将嵌套层OSIntNesting减一(OSIntNesting在每次进入一层中断时都会加一),直到OSIntNesting为0时,表面所有的嵌套中断都完成了,这是会判断此时最高优先级任务是什么,并执行OSIntCtxSw准备任务切换
任务的切换准备工作通过OSIntCtxSw完成,它将此时任务的SP指针指向lr,注意此时指向的是中断返回地址,这时我们将里面的内容换成任务切换的函数OS_TASK_SW_INT地址,那么当中断返回时,我们实际上指向的是OS_TASK_SW_INT
接下来的切换与10中基本一致
13、任务的挂起与恢复
OSTaskSuspend函数可以将任务手动挂起,通过将任务从任务就绪表中移除,并重启任务调度实现这一功能
OSTaskResume可以将被挂起的任务恢复就绪态,进行任务调度
参考:《多任务抢占式调度器》by Lisuwei
2021/8/14 0:14
LynnSX in HRB
【RTOS】《多任务抢占式调度器》笔记的更多相关文章
- VxWorks实验六 基于优先级的抢占式调度及实验的源程序和实验步骤
基于优先级的抢占式调度及实验的源程序和实验步骤 1 实验目的 1.学习并验证基于优先级的抢占式调度2 实验内容 在实验一建立的 project 中,创建3 个任务,对这三个任务使用基于优先 ...
- 循环引擎 greenlet 没有显式调度的微线程,换言之 协程
小结: 1. micro-thread with no implicit scheduling; coroutines, in other words. 没有显式调度的微线程,换言之 协程 2. 一个 ...
- based on Greenlets (via Eventlet and Gevent) fork 孙子worker 比较 gevent不是异步 协程原理 占位符 placeholder (Future, Promise, Deferred) 循环引擎 greenlet 没有显式调度的微线程,换言之 协程
gevent GitHub - gevent/gevent: Coroutine-based concurrency library for Python https://github.com/gev ...
- 深入理解Java虚拟机 第三章 垃圾收集器 笔记
1.1 垃圾收集器 垃圾收集器是内存回收的具体实现.以下讨论的收集器是基于JDK1.7Update14之后的HotSpot虚拟机.这个虚拟机包含的所有收集器有: 上图展示了7种作用于不同分代的收集 ...
- 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记
看<Python cookbook>的时候,第9.5部分,"定义一个属性可由用户修改的装饰器",有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了 完整代 ...
- k8s-调度器、预选策略及优选函数-二十
一.简介 master上运行着三个最核心的组件,apiserver.scheduler.controller manager.此外,master还依赖于ectd存储节点,最好ectd是有冗余能力的集群 ...
- Python装饰器笔记
DRY(Don't Repeat Yourself)原则: 一般是指在写代码的时候尽量避免重复的实现.违反DRY原则导致的坏处很容易理解,例如维护困难,修改时一旦遗漏就会产生不易察觉的问题. 一.函数 ...
- Storm系列(七)架构分析之Scheduler-调度器[DefaultScheduler]
Storm默认的任务调度器.实现如下: 1 (defn –prepare [this conf]) 2 (defn –schedule [this ^Topologies topologies ^ ...
- Storm系列(六)架构分析之Scheduler-调度器[EventScheduler]
任务调度接口定义: 1 IScheduler{ 2 // conf为当前nimbus的stormp配置 3 void prepare(Map conf); // 初始化 4 // to ...
- Python 装饰器(笔记,非原创)
定义:本质是函数,为其他函数添加附加功能原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式知识储备: 1.函数即“变量” 2.高阶函数 ...
随机推荐
- HJ92 在字符串中找出连续最长的数字串
描述 输入一个字符串,返回其最长的数字子串,以及其长度.若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置) 本题含有多组样例输入. 输入描述: 输入一个字符串. 输出描述: 输出字符串中 ...
- Ubuntu20.04 LTS更新源
Ubuntu 20.04 LTS Focal Fossa于2020年04月23日发布. 备份sudo cp /etc/apt/sources.list /etc/apt/sources.list.ba ...
- 12组-Beta冲刺-1/5
12组-Beta冲刺-1/5 一.基本情况 队名:字节不跳动 组长博客:https://www.cnblogs.com/147258369k/p/15590128.html Github链接:http ...
- Java基础学习:10、封装和继承和super、方法重载、多态、动态绑定
封装: 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.意义: 只能通过规定的方法访问数据. 隐藏类的实例细节,方便修改和实现 ...
- 使用layui+jQuery实现点击数据修改,即点即改。
使用layui+jQuery实现点击数据修改即可修改 首先要用到layui的官网手册 地址:https://www.layui.com/ 注意1. 此功能是在使用layui展示数据的基础上实现 3. ...
- JS脱敏姓名、身份证、电话、邮箱
一.姓名脱敏 handleName(name) { let arr = Array.from(name) let result = '' if (arr.length === 2) { result ...
- SQL_TIP_JOIN_x
没有条件的JOIN会导致数据数量变为两表的数据量的乘积结果. 用ON来在这些结果里进行筛选 on T1.A = T2.A的时候,如果T1的A是不重复的,则实际上是在对T2现有数据做筛选,结果数据量&l ...
- Node.js 源码解读 EventLoop
之前断断续续开发过一些 Node.js 的项目,但只仅限于使用它实现一些功能,没有过多对底层深入的研究.现在因为公司大前端组内的服务端渲染直出.BFF(Backend For Frontend) 等需 ...
- linux网卡配置模板(Rocky)
动态获取: tips: sudo nmcli con: 查询网卡UUID TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=dhcp ...
- pip python的包成功,但是import的时候报错
今天,一位同学线上反馈import python包失败了,同时附带两张图: 图1.报错代码 图2.报错提示 结合上面两个图片,我们发现这个同学import全部失败,初步怀疑该同学的本地环境上没有num ...