《多任务抢占式调度器》读书笔记

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】《多任务抢占式调度器》笔记的更多相关文章

  1. VxWorks实验六 基于优先级的抢占式调度及实验的源程序和实验步骤

    基于优先级的抢占式调度及实验的源程序和实验步骤 1 实验目的    1.学习并验证基于优先级的抢占式调度2 实验内容    在实验一建立的 project 中,创建3 个任务,对这三个任务使用基于优先 ...

  2. 循环引擎 greenlet 没有显式调度的微线程,换言之 协程

    小结: 1. micro-thread with no implicit scheduling; coroutines, in other words. 没有显式调度的微线程,换言之 协程 2. 一个 ...

  3. 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 ...

  4. 深入理解Java虚拟机 第三章 垃圾收集器 笔记

    1.1   垃圾收集器 垃圾收集器是内存回收的具体实现.以下讨论的收集器是基于JDK1.7Update14之后的HotSpot虚拟机.这个虚拟机包含的所有收集器有: 上图展示了7种作用于不同分代的收集 ...

  5. 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记

    看<Python cookbook>的时候,第9.5部分,"定义一个属性可由用户修改的装饰器",有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了 完整代 ...

  6. k8s-调度器、预选策略及优选函数-二十

    一.简介 master上运行着三个最核心的组件,apiserver.scheduler.controller manager.此外,master还依赖于ectd存储节点,最好ectd是有冗余能力的集群 ...

  7. Python装饰器笔记

    DRY(Don't Repeat Yourself)原则: 一般是指在写代码的时候尽量避免重复的实现.违反DRY原则导致的坏处很容易理解,例如维护困难,修改时一旦遗漏就会产生不易察觉的问题. 一.函数 ...

  8. Storm系列(七)架构分析之Scheduler-调度器[DefaultScheduler]

    Storm默认的任务调度器.实现如下: 1  (defn –prepare [this conf]) 2  (defn –schedule [this ^Topologies topologies ^ ...

  9. Storm系列(六)架构分析之Scheduler-调度器[EventScheduler]

    任务调度接口定义: 1  IScheduler{ 2      // conf为当前nimbus的stormp配置 3  void prepare(Map conf); // 初始化 4  // to ...

  10. Python 装饰器(笔记,非原创)

    定义:本质是函数,为其他函数添加附加功能原则:1.不能修改被装饰的函数的源代码         2.不能修改被装饰的函数的调用方式知识储备:       1.函数即“变量”       2.高阶函数  ...

随机推荐

  1. 01Java常用类

    Object类 Object概述 Object类是超类,基类,所有类都默认直接继承Object类. Object类中定义的方法,是所有对象都具备的方法. Object类可以存储任何类 ​ - 可以作为 ...

  2. idea主题插件 ->Atom Material File Icons

    Atom Material File Icons    插件名

  3. 【转载】Adobe Acrobat XI Pro闪退原因及解决办法

    https://www.cnblogs.com/zohoo/p/12704689.html https://www.cnblogs.com/zohoo/p/12704689.html

  4. docker 运行环境

    步骤 1 - 启用适用于 Linux 的 Windows 子系统 需要先启用"适用于 Linux 的 Windows 子系统"可选功能,然后才能在 Windows 上安装 Linu ...

  5. 遇到端口占用无法启动IIS Express服务器

    报错图片: 上图所述由于端口被占用无法完成IIS Express的输出 这时候要考虑到自己在Windows的IIS 是不是配置了该端口? 很明显,就是配置了一个8091的端口且还在启动中,这时候要先将 ...

  6. js中,作用域与作用域链的概念

    1 作用域 声明的一个变量只在一段代码范围内是有效的,并不是总有效的.例如 : function father(){ // 声明变量 var val = "作用域内"; // 定义 ...

  7. potoshop制作一寸照片

    potoshop制作一寸照片 经常因为各种原因需要提供1寸照片,第一反应应还是跑照相馆专业.但是疫情封闭在家怎么高,刚好把偶尔使用一次的potoshop用起来,解决照片制作问题,一来能省几毛钱买茶叶蛋 ...

  8. 【git】3.5 git分支-远程分支

    资料来源 (1) https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E8%BF%9C%E7%A8%8B%E5%88%86%E6%94%AF ...

  9. 如何在winform打包时带上sqlite数据库

    sqlite数据库下载及使用:https://blog.csdn.net/Yyuanyuxin/article/details/105508886sqlite数据库可视化工具-- DB.Browser ...

  10. wpf 解决画图模糊或抗锯齿以及文字模糊或抗锯齿问题

    解决方案中使用的.Net FrameWork版本:4.6.1 画图模糊或抗锯齿: 控件属性加入  SnapsToDevicePixels="True" 文字模糊或抗锯齿: 控件属性 ...