μcOS-II多任务实验报告(RMS、EDF调度)

一、实验概述

  • 实验目的:在ucOS-II上多任务实验,要求考虑到任务间存在共享资源的情况。
  • 本次实验使用到的调度策略为RMS和EDF。
  • 其中RMS为固定优先级的调度,其实就是从就绪态中找到优先级最大的,就是周期最小的让它进入运行态。
  • 而EDF调度起源于EDD算法,EDD算法要求最小化最大延迟,只要将ddl近的设为高优先级就行了,而EDF要求进一步支持任务在任意时间到达,即EDF需要动态的维持任务的优先级。
  • 共享资源利用信号量OSSemCreate(1)实现
  • 备注:在提交的作业中,我把Sched_EDF()注释掉了,默认输出结果是RMS调度(有共享资源)。想看EDF的结果就到oscore.c中,找到OS_SchedNew(),把RMS调度注释掉,清除EDF的注释。想看无共享资源就到main.c,找到对任务resource初始化的代码,注释掉即可。

二、环境搭建

本实验使用的μcOS-II系统,是移植到VS2017上的。在打开解决方案OS2.sln后,发现其使用的Windows SDK版本较旧,因此需要在项目属性中重新指定SDK版本。重新配置后,项目能够正常编译运行。

三、代码分析

在借助资料,研读代码执行流程后,我认识到:

  • 任务在main.c中创建,新建任务后会生成对应的TCB程序控制块(定义在ucos-ii.h中的OS_TCB),并链接到TCB链表中头,链表尾是程序创建的空闲任务。
  • 任务在while中无限循环,cpu利用TimeTick(在os_cpu_c.c中)在这些任务中切换。每隔一段时间中断,中断调用函数OSTickW32,顺序执行OSIntEnter()、OSTimeTick()、OSIntExit()、OSIntCurTaskResume()。
  • 中断主要使用的函数OSTimeTick()在os_core.c中,它会遍历OSTCBList,将所有TCB的等待时间(ptcb->OSTCBDly)减一,如果那个TCB的等待时间变成0了,就把它的优先级添加到任务就绪表。
  • 再看OSIntExit(),也在os_core.c中,通过OSPrioHighRdy,然后去OSTCBPrioTbl数组找到了对应的TCB,赋值给OSTCBHighRdy指针。然后调用了上下文切换函数OSIntCtxSw()函数(用来切换线程,修改了OSTCBCur,OSPrioCur)。
  • 值得注意的是,在OSIntExit()中程序是通过OS_SchedNew()来取得当前就绪态中优先级最高的TCB块的,用OSPrioHighRdy表示。
  • 而OS_SchedNew()(同在os_core.c中),仅仅通过三行关键代码(就在<=63的那个if里)就完成了对RMS的支持。如果想修改调度算法,应该就是改这里了。

四、实验步骤

1 给TCB块添加扩展

如下图所示,定义在ucos_ii.h中的OS_TCB下面,在创建任务时作为TCB扩展传入。OS_TCB的OSTCBExtPtr指针指向的就是这个tcb_ext_info。目的是为执行任务时提供必要的信息

2 创建并执行任务

  • 如下图所示,进行了任务创建(createTasks)与任务执行(startTasks)。都在main.c中。

  • 任务创建要初始化resource,即信号量的事件控制块指针,然后使用OSTaskCreateExt()方法创建任务。其中任务的id号=任务的优先值=任务的周期数。因为任务的优先级和任务的优先值成反比。其中对于RMS调度,任务的优先级与任务的周期成反比,也就是说任务优先值是可以直接用周期表示的。其中对于EDF调度,这个动态优先级调度,也省得我重新为三个任务指定初始优先值,对于这个用例我就默认任务初始优先值等于周期长度。

  • 任务执行先使用while循环来做一个周期的任务,利用时钟中断来切换任务。所以这个周期可能会顺利执行完,也有可能被抢占,执行可能会请求信号量。一个周期做完了,要重置rest_c并记得归还信号量。







3 添加时钟中断对剩余执行时间和剩余周期的操作

在os_core.c中每次timetick,把执行任务的rest_c减去1,并遍历TCB,把所有任务的rest_p减去1,并看哪个任务已经OSTCBDly已经为0,即进入就绪态时再重置任务的rest_p。

4 实现调度

注释掉OS_SchedNew()中的函数,在结尾插入我的新函数Sched_RMS和Sched_EDF()。

4.1 RMS调度

考虑到要实现共享资源,这三行代码还不太利于我操作,尤其是目前我对代码了解还不深的情况下。考虑到RMS较为简单,我就用自己添加的数据结构重新写了RMS调度。重新写好处是,一来EDF完全可以复用它,只要把就绪态中周期最小的改为就绪态中剩余周期最小的就行了;二来,这样方便我过滤掉就绪态中资源被别的任务占用的任务。

主要思路是初始优先级选63,遍历TCB链表(不包括61,62),找到就绪态中可请求资源或无需资源的任务中优先级最高(周期最短)的任务,如果需要请求资源,就给它资源。



4.2 EDF调度

EDF复用RMS的代码,只要把就绪态中周期最小的改为就绪态中剩余周期最小的就行了。



5 输出

两种输出,任务完成与任务抢占

  • 任务完成会调用OSTimeDly(),完成的printf写在该函数里
  • 任务抢占会走OSIntExit(),在该函数里判断一下是不是抢占,如果是就printf抢占的内容。

6 结果展示

6.1 RMS 无共享资源

6.2 EDF 无共享资源

6.3 RMS 有共享资源(最高优先级和最低优先级共享)

6.4 EDF有共享资源(最高优先级和最低优先级共享)

五 值得注意的部分

  • 遍历的时候要注意不单单有优先级为63的空闲任务,我还发现了有优先级为62、61的任务,为了方便输出的观察,我是直接将其过滤掉,不让其影响我的输出。
  • 注意可能存在这种情况,在B任务执行结束时,即rest_c=0时,如果A任务优先级高于B,会发生A先抢占B,然后A执行完之后……然后B任务才能complete。这点给我造成了很大的两点麻烦。
    • 一个是我不希望造成A抢占B,然后某任务再还给B的这种输出,而是应该让B直接完成,然后再让A做其他操作。这个我是通过给任务抢占的判断添加限制条件(在任务抢占输出那一部分),让B能跳过被抢占,直接完成,完成后再转给A。
    • 另一个是我不希望由于A抢占B,B不能立即complete造成资源还在B手里,不能归还,影响其它任务的执行。这点我通过在调度函数最后请求资源时做条件判断,避免了这种情况。
  • 给代码加入信号量部分后,发现代码运行出问题了,导致进入临界区函数OS_ENTER_CRITICAL()没法使用了,导致下面代码运行不了。在找到该函数源码后,依据网上给的思路,我试着换到另一个if判断,并注释掉了一部分代码后,能够正常运行。
  • 还有一个问题是,时钟频率太快导致代码来不及运行,这个我一开始不知道,毫无办法,后来把os_cfg.h文件中#define OS_TICKS_PER_SEC 从100改成10,这样运行就没问题了。

六 源码

github源码

基于μcOS-II实时操作系统源码实现RMS和EDF调度(共享资源)的更多相关文章

  1. 适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

    本文由“yuanrw”分享,博客:juejin.im/user/5cefab8451882510eb758606,收录时内容有改动和修订. 0.引言 站长提示:本文适合IM新手阅读,但最好有一定的网络 ...

  2. 基于vitamio的网络电视直播源码

    这个项目是基于vitamio的网络电视直播源码,也是一个使用了vitamio的基于安卓的网络直播项目源码,可能现在网上已经有很多类似这样的视频播放应用了,不过这个还是相对来说比较完整的,希望这个案例能 ...

  3. 第6章 RTX 操作系统源码方式移植

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章教程为大家将介绍 RTX 操作系统源码方式移植,移植工作比较简单,只需要用户添加需要的源码文件即可, ...

  4. 基于jQuery经典扫雷游戏源码

    分享一款基于jQuery经典扫雷游戏源码.这是一款网页版扫雷小游戏特效代码下载.效果图如下: 在线预览   源码下载 实现的代码. html代码: <center> <h1>j ...

  5. Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析

    Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析 本文简要介绍了基于 Spring 的 web project 的启动流程,详细分析了 Spring 框架将开发人员基于 XML ...

  6. Spark源码分析之六:Task调度(二)

    话说在<Spark源码分析之五:Task调度(一)>一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法.这个方法针对接收到的ReviveOffer ...

  7. 基于Linux平台的libpcap源码分析和优化

    目录 1..... libpcap简介... 1 2..... libpcap捕包过程... 2 2.1        数据包基本捕包流程... 2 2.2        libpcap捕包过程... ...

  8. 基于ReentrantLock的AQS的源码分析(独占、非中断、不超时部分)

    刚刚看完了并发实践这本书,算是理论具备了,看到了AQS的介绍,再看看源码,发现要想把并发理解透还是很难得,花了几个小时细分析了一下把可能出现的场景尽可能的往代码中去套,还是有些收获,但是真的很费脑,还 ...

  9. Android版数据结构与算法(二):基于数组的实现ArrayList源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 本片我们分析基础数组的实现--ArrayList,不会分析整个集合的继承体系,这不是本系列文章重点. 源码分析都是基于"安卓版" ...

随机推荐

  1. A - 规律题

    我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目.比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示. Input输 ...

  2. CF 1326 D. Prefix-Suffix Palindrome

    D. Prefix-Suffix Palindrome 题意 给一个字符串 s,求一个字符串 t,t 由 s 的某个前缀以及某个后缀拼接而成,且 t 是回文串,长度不能超过 s.输出最长的 t 分析 ...

  3. 【bzoj 1190】梦幻岛宝珠(DP)

    这题是在01背包问题的基础上,扩充了重量,需要用时间换空间. 思路: 1.仔细看题,注意到重量wi为a*2^b(a<=10,b<=30),很容易想到要按 b 分开做背包的DP.接下来的重点 ...

  4. Atcoder Panasonic Programming Contest 2020

    前三题随便写,D题是一道dfs的水题,但当时没有找到规律,直接卡到结束 A - Kth Term /  Time Limit: 2 sec / Memory Limit: 1024 MB Score ...

  5. HDU - 1059 背包dp

    题目: 有两个小朋友想要平分一大堆糖果,但他们不知道如何平分需要你的帮助,由于没有spj我们只需回答能否平分即可. 糖果大小有6种分别是1.2.3.4.5.6,每种若干颗,现在需要知道能不能将这些糖果 ...

  6. EGADS介绍(二)--时序模型和异常检测模型算法的核心思想

    EDADS系统包含了众多的时序模型和异常检测模型,这些模型的处理会输入很多参数,若仅使用默认的参数,那么时序模型预测的准确率将无法提高,异常检测模型的误报率也无法降低,甚至针对某些时间序列这些模型将无 ...

  7. leetcode5 最长回文字符串 动态规划 Manacher法

    dp 注意没有声明S不空,处理一下 o(n^2) class Solution { public: string longestPalindrome(string s) { if (s.empty() ...

  8. codeforces 1039B Subway Pursuit【二分+随机】

    题目:戳这里 题意:一个点在[1,n]以内,我们可以进行4500次查询,每次查询之后,该点会向左或向右移动0~k步,请在4500次查询以内找到该点. 解题思路:一边二分,一边随机. 交互题似乎有好多是 ...

  9. 334A Candy Bags

    A. Candy Bags time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  10. Hexo-域名设置+收录

    Hexo-域名设置+Github域名加速+网址收录 Github.Gitee绑定域名,然后进行网址收录. 不想购买域名也完全可以进行网址收录. 购买阿里云域名 1.进入阿里云域名网站 2.进入价格详情 ...