uC/OS-II源码分析(六)

简介:

μC/OS-Ⅱ总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高,

下面该哪个任务运行了的工作是由调度器(Scheduler)完成的。任务级的调度是由函数

OSSched()完成的。中断级的调度是由另一个函数OSIntExt() 完成的,这个函数将在以后描

述。OSSched() 的代码如下:

void OS_Sched (void)

{

#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */

OS_CPU_SR cpu_sr;

#endif

INT8U y;

OS_ENTER_CRITICAL();

if ((OSIntNesting == 0) && (OSLockNesting == 0))

{ /* 只有ISR完成同时没有锁住调度才进行切换 */

//找最高优先级的任务

y = OSUnMapTbl[OSRdyGrp];

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

if (OSPrioHighRdy != OSPrioCur)

{ /*检查寻找到的优先级最高的任务是否是当前正在运行的任务,若是则不进行调度*/

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];//指向优先级最高的任务控制块

OSCtxSwCtr++; /* 切换计数器加*/

OS_TASK_SW(); /* 进行实际的任务切换*/

}

}

OS_EXIT_CRITICAL();

}

#define uCOS 0x80 /*用于任务切换的中断向量*/

#define OS_TASK_SW() asm INT uCOS

μC/OS-Ⅱ任务调度所花的时间是常数,与应用程序中建立的任务数无关。任务切换很简单,由以下两步完成,将被挂起任务的微处理器寄存器推入堆栈,然后将较高优先级的任务的寄存器值从栈中恢复到寄存器中。在μC/OS-Ⅱ中,就绪任务的栈结构总是看起来跟刚刚发生过中断一样,所有微处理器的寄存器都保存在栈中。换句话说,μC/OS-Ⅱ运行就绪态的任务所要做的一切,只是恢复所有的CPU 寄存器并运行中断返回指令。为了做任务切换,运行OS_TASK_SW(), 人为模仿了一次中断。多数微处理器有软中断指令或者陷阱指令TRAP 来实现上述操作。中断服务子程序或陷阱处理(Trap hardler),也称作事故处理(exception handler),必须提供中断向量给汇编语言函数OSCtxSw() 。OSCtxSw() 除了需要OS_TCBHighRdy 指向即将被挂起的任务,还需要让当前任务控制块OSTCBCur 指向即将被挂起的任务,

OSSched()的所有代码都属临界段代码。在寻找进入就绪态的优先级最高的任务过程中,

为防止中断服务子程序把一个或几个任务的就绪位置位,中断是被关掉的。为缩短切换时间,

OSSched()全部代码都可以用汇编语言写。为增加可读性,可移植性和将汇编语言代码最少

化,OSSched() 是用C 写的。

OSCtxSw代码:

_OSCtxSw PROC FAR

PUSHA ; 保存当前任务的上下文

PUSH ES ;

PUSH DS ;

MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered

MOV DS, AX ;

LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP

MOV ES:[BX+2], SS ;

MOV ES:[BX+0], SP ;

CALL FAR PTR _OSTaskSwHook ; Call user defined task switch hook

MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy

MOV DX, WORD PTR DS:_OSTCBHighRdy ;

MOV WORD PTR DS:_OSTCBCur+2, AX ;

MOV WORD PTR DS:_OSTCBCur, DX ;

MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy

MOV BYTE PTR DS:_OSPrioCur, AL ;

LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr

MOV SS, ES:[BX+2] ;

MOV SP, ES:[BX] ;

POP DS ; 加载新任务的上下文

POP ES ;

POPA ;

IRET ; 返回到新任务中

_OSCtxSw ENDP

3. 给调度器上锁和开锁(Locking and UnLocking the Scheduler)

给调度器上锁函数OSSchedlock()用于禁止任务调度,直到任务完成后调用给调度器开锁函数OSSchedUnlock() 为止。调用OSSchedlock() 的任务保持对CPU 的控制权,尽管有个优先级更高的任务进入了就绪态。然而,此时中断是可以被识别的,中断服务也能得到(假设中断是开着的)。OSSchedlock() 和OSSchedUnlock() 必须成对使用。变量OSLockNesting 跟踪OSSchedLock() 函数被调用的次数,以允许嵌套的函数包含临界段代码,这段代码其它任务不得干预。μC/OS-Ⅱ允许嵌套深度达255 层。当OSLockNesting 等于零时,调度重新得到允许。函数OSSchedLock() 和OSSchedUnlock() 的使用要非常谨慎,因为它们影响μC/OS-Ⅱ对任务的正常管理。

当OSLockNesting 减到零的时候, OSSchedUnlock() 调用OSSched[L3.10(2)] 。

OSSchedUnlock() 是被某任务调用的,在调度器上锁的期间,可能有什么事件发生了并使一

个更高优先级的任务进入就绪态。

调用OSSchedLock() 以后,用户的应用程序不得使用任何能将现行任务挂起的系统调

用。也就是说,用户程序不得调用OSMboxPend() 、OSQPend() 、OSSemPend() 、

OSTaskSuspend(OS_PR1O_SELF) 、OSTimeDly() 或OSTimeDlyHMSM(), 直到OSLockNesting 回零为止。因为调度器上了锁,用户就锁住了系统,任何其它任务都不能运行。

当低优先级的任务要发消息给多任务的邮箱、消息队列、信号量时,用户不希望高优先级的任务在邮箱、队列和信号量没有得到消息之前就取得了CPU 的控制权,此时,用户可以使用禁止调度器函数。

给调度器上锁

void OSSchedLock (void)

{

if (OSRunning == TRUE)

{

OS_ENTER_CRITICAL();

OSLockNesting++;

OS_EXIT_CRITICAL();

}

}

给调度器开锁.

void OSSchedUnlock (void)

{

if (OSRunning == TRUE) {

OS_ENTER_CRITICAL();

if (OSLockNesting > 0) {

OSLockNesting--;

if ((OSLockNesting | OSIntNesting) == 0) {

OS_EXIT_CRITICAL();

OSSched();

} else {

OS_EXIT_CRITICAL();

}

} else {

OS_EXIT_CRITICAL();

}

}

}

目录
相关文章
|
Web App开发 调度
|
Web App开发 消息中间件 存储
|
Web App开发 调度 消息中间件
|
Web App开发 调度 消息中间件
|
消息中间件 Web App开发 存储
|
2月前
|
Web App开发 缓存 Rust
|
2月前
|
Ubuntu Unix Linux
操作系统的最强入门科普(Unix/Linux篇)
下期文章,小枣君会重点聊聊Windows和macOS那条线。敬请关注! 如果大家觉得文章不错,还请帮忙多多转发!谢谢!
|
11月前
|
安全 Linux 数据安全/隐私保护
Vanilla OS:下一代安全 Linux 发行版
【10月更文挑战第30天】
464 0
Vanilla OS:下一代安全 Linux 发行版
|
8月前
|
运维 自然语言处理 Ubuntu
OS Copilot-操作系统智能助手-Linux新手小白的福音
OS Copilot 是阿里云推出的一款操作系统智能助手,专为Linux新手设计,支持自然语言问答、辅助命令执行和系统运维调优等功能。通过简单的命令行操作,用户可以快速获取所需信息并执行任务,极大提升了Linux系统的使用效率。安装步骤简单,只需在阿里云服务器上运行几条命令即可完成部署。使用过程中,OS Copilot不仅能帮助查找命令,还能处理文件和复杂场景,显著节省了查找资料的时间。体验中发现,部分输出格式和偶尔出现的英文提示有待优化,但整体非常实用,特别适合Linux初学者。
390 10

热门文章

最新文章

  • 1
    【独家揭秘2025】VMware Workstation Pro虚拟机:免费安装教程大放送,一键解锁操作系统模拟神器!
    500
  • 2
    【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
    285
  • 3
    追踪隐式资源,巧解内存难题!阿里云操作系统控制台上线
    160
  • 4
    云产品评测|操作系统智能助手OS Copilot新功能获奖名单公布!
    231
  • 5
    Harmony OS开发-ArkTS三
    345
  • 6
    docker快速部署OS web中间件 数据库 编程应用
    211
  • 7
    【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
    324
  • 8
    操作系统控制台体验测评
    336
  • 9
    【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
    359
  • 10
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
    367
  • 推荐镜像

    更多