这一片谈谈关于ucos调度器的相关知识.

ucos的调度器的实现主要靠一个函数OS_Sched

该函数将调度器的行为分为了两个部分,第一是调度部分,第二是任务切换部分,如下

void  OS_Sched (void)

{

#if OS_CRITICAL_METHOD == 3u

OS_CPU_SR  cpu_sr = 0u;

#endif

OS_ENTER_CRITICAL();

if (OSIntNesting == 0u) {

if (OSLockNesting == 0u) {

OS_SchedNew();

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

if (OSPrioHighRdy != OSPrioCur) {

#if OS_TASK_PROFILE_EN > 0u

OSTCBHighRdy->OSTCBCtxSwCtr++;

#endif

OSCtxSwCtr++;

OS_TASK_SW();

}

}

}

OS_EXIT_CRITICAL();

}

这段代码中使用了两个全部变量,分别是

OSIntNesting

OSLockNesting

第一个变量在系统中断的时候调用OSIntEnter使之+1,退出中断的时候使用OSIntExit使之-1,这样就能保证调度的时候系统中是没有中断的, OS_ENTER_CRITICAL这个代码关闭了中断,

第二个变量是一个调度锁,由OSSchedLock使之+1 OSSchedUnlock使之-1,用来在系统中短暂的屏蔽调度器的运行

此时可以看到,调度发生的时候,系统处于无中断而且调度器没有加锁的情况下,调用OS_SchedNew函数,该函数部分源码为

y   = OSUnMapTbl[OSRdyGrp];

OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);

还有部分源码也是相同的功能,只是63优先级扩展到255优先级,查找就绪表的过程变化了而已

OSPrioHighRdy表示了当前系统中准备好的最高优先级的任务的优先级,通过优先级找到最高优先级(准备好的)的系统tcb,并确保不是当前正在运行的任务的优先级,然后跳转到OS_TASK_SW进行任务切换

OS_TASK_SW是一个任务切换宏,展开来就是OSCtxSw函数,,是需要用户实现的一个接口代码,如下

OSCtxSw

PUSH    {R4, R5}

LDR     R4, =NVIC_INT_CTRL  ;触发PendSV异常(causes context switch)

LDR     R5, =NVIC_PENDSVSET

STR     R5, [R4]

POP     {R4, R5}

BX      LR

这段代码出发了一个pend_sv的异常,那么应该就到了中断处理函数中

中断处理函数挺长的,这里就不贴代码了,但是其核心功能就是比较当前任务优先级和最高ready任务优先级,进行堆栈指针psp的切换和相应的赋值操作(tcbcur),当退出中断的时候就能实现任务切换了.具体来说,这个函数应当完成七个功能

把当前任务的端点指针保存到当前任务堆栈中

把处理器通用寄存器的内容保存到任务堆栈中

把被终止任务的任务堆栈指针当前值保存到该任务任务控制块的OSTCBSTKpTR中

获得待运行任务的任务控制块

是处理器通过任务控制块获得待运行任务的任务堆栈指针

将待运行任务的任务堆栈指针中的数据恢复到cpu他通过寄存器

使处理器获得待运行任务的断点指针

通过这里我们可以看到,如果一个任务占有最高优先级,而任务本身不对资源进行释放,也就是任务本身不去修改系统就绪表的话,这个任务将一直执行,除非出现更高级的任务.

说到这里,为什么要在终端中进行任务切换呢?原因在于,pc指针无法通过指令压入堆栈,但是能够在中断情况下cpu自动把pc压入堆栈,我们要获取pc指针,就只能通过堆栈了

以上所说的都是在正常情况下的任务切换,ucos在中断环境下也能进行任务切换,这个任务切换是通过函数OSIntExit函数来实现的,核心代码如下

if (OSRunning == OS_TRUE) {

OS_ENTER_CRITICAL();

if (OSIntNesting > 0u) {

OSIntNesting--;

}

if (OSIntNesting == 0u) {

if (OSLockNesting == 0u) {

OS_SchedNew();

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

if (OSPrioHighRdy != OSPrioCur) {

#if OS_TASK_PROFILE_EN > 0u

OSTCBHighRdy->OSTCBCtxSwCtr++;

#endif

OSCtxSwCtr++;

OSIntCtxSw();

}

之前说到,退出中断的时候调用这个函数,将OSIntNesting-1,之后处理器会进行一次任务切换,别的地方都和OSSched()函数一致,只是任务切换的时候使用的切换函数是OSIntCtxSw函数,该函数原型如下

OSIntCtxSw

PUSH    {R4, R5}

LDR     R4, =NVIC_INT_CTRL      ;触发PendSV异常 (causes context switch)

LDR     R5, =NVIC_PENDSVSET

STR     R5, [R4]

POP     {R4, R5}

BX      LR

NOP

和之前的OSCtxSw是一致的

经过上面的分析,知道了系统调度的具体过程,任务切换的时机就可以说是两个了,第一个是调用OSSched和中断中OSIntExit,而OSSched的调用在系统中哪些位置一查便知

多说一句,在不使用任务同步特性的情况下,最经常的造成任务调度的方法是OSTimeDly时钟延时的时候,任务调度的最终实现通过中断完成.

ucos调度器详解的更多相关文章

  1. 3、lvs调度方法详解

    3.lvs类型和调度方法详解    http://www.178linux.com/13570 集群:将多台主机组织起来满足某一特定需求: 集群类型: LB:Load Balancing, 负载均衡集 ...

  2. GLSL-几何着色器详解跟实例(GS:Geometry Shader)[转]

    [OpenGL4.0]GLSL-几何着色器详解和实例(GS:Geometry Shader) 一.什么是几何着色器(GS:Geometry Shader) Input Assembler(IA)从顶点 ...

  3. C编译器、链接器、加载器详解

    摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代 ...

  4. Java类加载器详解

    title: Java类加载器详解date: 2015-10-20 18:16:52tags: JVM--- ## JVM三种类型的类加载器- 我们首先看一下JVM预定义的三种类型类加载器,当一个 J ...

  5. JMeter 后置处理器之正则表达式提取器详解

    后置处理器之正则表达式提取器详解   by:授客 QQ:1033553122 1. 添加正则表达式提取器 右键线程组->添加->后置处理器->正则表达式提取器 2. 提取器配置介绍 ...

  6. Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)

    一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...

  7. Lucene系列三:Lucene分词器详解、实现自己的一个分词器

    一.Lucene分词器详解 1. Lucene-分词器API (1)org.apache.lucene.analysi.Analyzer 分析器,分词器组件的核心API,它的职责:构建真正对文本进行分 ...

  8. python设计模式之装饰器详解(三)

    python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...

  9. Jmeter 正则表达式提取器详解(Regular Expression Exactor)

    Jmeter 正则表达式提取器详解(Regular Expression Exactor) Name(名称):随意设置,最好有业务意义. Comments(注释):随意设置,可以为空 Apply to ...

随机推荐

  1. encodeURIComponent与URLDecoder.decode用法

    在输入地址栏时有时一些信息需要在地址栏看不见,我们就需要对其信息在前台转码后台解码 js:encodeURIComponent编码与解码 今天在js往jsp和servlet传参的时候出现:JavaSc ...

  2. win8.1去掉鼠标右键回收站固定到开始菜单的方法

    win8.1去掉鼠标右键“回收站固定到开始菜单” 平台:win8.1 问题: 桌面“回收站”右键菜单里有个“固定到开始屏幕”,一不小心就误按,设法删之. 打开注册表编辑器.在注册表编辑器里面定位到:H ...

  3. PullToRefreshScrollView的上拉加载、下拉刷新

    eclipse中的项目: //注意:此刷新功能是使用的第三方的PullToRefreshScrollView,因此需要导入第三方library作为依赖 步骤:导入第三方library,依赖:点击你的应 ...

  4. IDAPython: importing “site” failed

    问题:IDA启动时,弹出IDAPython: importing “site” failed对话框. 解决办法:环境变量添加PYTHONHOME,值为python安装路径,比如:C:\Python27

  5. C++的精髓——虚函数

    虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚函数 引入原 ...

  6. HDU1253--胜利大逃亡--HDU1240--Asteroids!--简单三维BFS

    胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  7. ubuntu 12.04 安装snort acidbase相关注意事项

    一.安装Snort 1.安装libpcap 1 apt-get install libpcap-dev 2.安装snort 1 2 apt-get install snort apt-get inst ...

  8. PAT (Advanced Level) 1103. Integer Factorization (30)

    暴力搜索. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #i ...

  9. java OPENCV 连通域, Imgproc.findContours 例子,参数说明

    http://stackoverflow.com/questions/29491669/real-time-paper-sheet-detection-using-opencv-in-android/ ...

  10. VIJOS P1647 不差钱 SBT

    [描述] 同学们一起看了小品<不差钱>,LX神突发奇想,想刁难一下十八居士,他让十八居士模拟一下点菜的过程. [输入格式] 输入第一行为一个数price,表示价钱大于price的菜赵本山都 ...