【原创】uC/OS II 任务切换原理
今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS、IP寄存器没有出栈和入栈指令,所以只能引发一次中断,自动将CS、IP寄存器压入堆栈,再利用中断返回,将新任务的任务断点指针弹出到CPU的CS、IP寄存器中,实现任务切换。虽然明白个大概,但是其中的细节却有点模糊,为什么调用IRET中断返回指令后,弹入CPU的CS、IP寄存器的断点指针是新任务的断点指针,而不是当前任务的,UCOS II是如何实现这个过程的?网上的文章没有提及任务切换的细节,然而这些细节却是理解的重点,所以才有了今天这一篇文章!
//!!!为简单说明问题,OS_Sched中特意删减了一些语句
void OS_Sched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
y =OSUnMapTbl[OSRdyGrp];
//得到最高优先级任务,OSPrioHighRdy从此为就绪表中最高优先级任务的优先级别
OSPrioHighRdy=(INT8U)((y <<)+OSUnMapTbl[OSRdyTbl[y]]);
//判断当前任务是否为就绪表中最高优先级任务
if(OSPrioHighRdy!=OSPrioCur)
{
//得到新任务的任务控制块的指针
OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];
//统计任务切换次数的计数器加1
OSCtxSwCtr++;
//此句关键!使用软件中断切换任务,OS_TASK_SW()其实为INT 0x80,128号中断
//中断产生后,CPU依次将PSW状态寄存器、断点指针段地址:偏移地址压入当前任务的堆栈中
OS_TASK_SW();
}
OS_EXIT_CRITICAL();
}
_OSCtxSw PROC FAR
;
;保存当前任务寄存器内容,将它们压入当前任务堆栈,AX、CX、DX、BX、SP(原始值)、BP、SI 及 DI
PUSHA ;
PUSH ES ;
PUSH DS ;
;
;将当前任务的任务控制块的指针段地址赋值给DS寄存器
MOV AX, SEG _OSTCBCur;Reload DS in case it was altered
MOV DS, AX ;
;
; LES指令作用,取得OSTCBCur变量内容(因为任务控制块的第一个成员为任务堆栈指针,所以ES:[BX+0]表示的地址不仅是任务控制块的首地址,也是任务堆栈指针的地址),低字存放于BX,高字存放于ES,有关LES详细查看另一篇文章!
;同时由于任务控制块的第一成员为任务堆栈指针变量,所以任务堆栈指针成员变量的地址和任务控制块的地址一样
LES BX, DWORD PTR DS:_OSTCBCur; OSTCBCur->OSTCBStkPtr = SS:SP!!!
MOV ES:[BX+], SS ;将当前SS(栈的基地址)寄存器值存放至当前任务控制块的2,3内存单元
MOV ES:[BX+], SP ;将当前SP(栈顶的偏移量)存放至当前任务控制块的0,1内存单元
;
CALL FAR PTR _OSTaskSwHook;Call user defined task switch hook
;
;存储器寻址,DS:_OSTCBHighRdy+2存放的是新任务的栈基址SS,DS:_OSTCBHighRdy存放的是栈顶偏移量SP
MOV AX, WORD PTR DS:_OSTCBHighRdy+;将OSTCBHighRdy赋值给OSTCBCur,使OSTCBCur指向新的任务控制块
MOV DX, WORD PTR DS:_OSTCBHighRdy;OSTCBCur=OSTCBHighRdy
MOV WORD PTR DS:_OSTCBCur+, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy;OSPrioCur=OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL ;
;
;将最高级优先级任务的任务控制块包含的SS和SP寄存器值,CPU的SS和SP指向了新的任务堆栈
LES BX, DWORD PTR DS:_OSTCBHighRdy; SS:SP =OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+];
MOV SP, ES:[BX];
;
;注意:这里弹出的是新任务的堆栈,而不是旧的,因为CPU的SS和SP已经指向了新的任务堆栈
POP DS ;Loadnew task's context
POP ES ;
POPA ;
;
;当新任务的堆栈都弹出的时候,只剩下新任务的CS、IP指针,刚好运行IRET弹到CPU的CS、IP寄存器,开始新任务的运行
IRET ;Return to new task
;
_OSCtxSw ENDP


本文链接:http://www.cnblogs.com/cposture/p/4291503.html
【原创】uC/OS II 任务切换原理的更多相关文章
- uC/OS II原理分析及源码阅读(一)
uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...
- 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II
SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...
- uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()
1. OSTaskCreate() OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构. ...
- uc/os iii移植到STM32F4---IAR开发环境
也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢 ...
- 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理
LES BX, DWORD PTR DS:_OSTCBCur ;OSTCBCur->OSTCBStkPtr = SS:SP!!! ], SS ;将当前SS(栈的基地址)寄存器值存放至当前任务控制 ...
- 在STM32F401上移植uC/OS的一个小问题 [原创]
STM32F401xx是意法半导体新推出的Cortex-M4内核的MCU,相较于已经非常流行的STM32F407xx和STM32F427xx等相同内核的MCU而言,其特点是功耗仅为128uA/MHz, ...
- 关于uC/OS的简单学习(转)
1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数, ...
- uc/os任务创建
问题描述: uc/os中任务创建 问题解决: 创建一个任务,任务从无到有.任务创建函数分两种, 一种是基本的创建函数OSTaskCreate, 另一种是扩展的任务创建函数OSTaskCrea ...
- uC/OS 的任务调度解析 (转)
uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS ...
随机推荐
- MacBook上那些好用的工具们
https://blog.csdn.net/qq_33833327/article/details/78454703
- python3中报错:TypeError: 'range' object doesn't support item deletion
1.源代码 以下代码执行时会报 range' object does not support item assignment 的错误,问题出现在第17行的runge(10): import unit ...
- js基础知识1:标识符 注释
何为标识符:意思是标记识别的的符号,简称标识符,主要的用途声明变量,函数的名字,属性以及函数中的参数. 标识符的规则1:首先第一个字符必须是字母(abcABC),_(下划线),$(美元符号).不能是( ...
- 【python-时间戳】时间与时间戳之间的转换
对于时间数据,如2016-05-05 20:28:54,有时需要与时间戳进行相互的运算,此时就需要对两种形式进行转换,在Python中,转换时需要用到time模块,具体的操作有如下的几种: 将时间转换 ...
- MVC概述
学习MVC模式 一.MVC简介 MVC是Model-View-Controller的简称,即模型-视图-控制器.MVC是一种设计模式,它把应用程序分成三个核心模块:模型.视图.控制器,它们各自处理 ...
- django2+python3+uwsgi+centos7部署网站
Centos7中安装Python虚拟环境 2018年08月27日 00:09:36 kaichenkai 阅读数:984 1.为什么要搭建虚拟环境? 问题:如果在一台电脑上, 想开发多个不同的项目, ...
- linux之配置Mongodb~
OK 让我们先下载一波mongodb~(64位ubuntu) curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0. ...
- Maven4-仓库
坐标和构建是一个构件在Maven世界中的逻辑表示方式,而其物理表示方式是文件.Maven通过仓库来统一管理这些文件 什么是Maven仓库? 在Maven世界中,任何一个依赖,插件或者项目构建的输出,都 ...
- nova compute enable password injection and filesystem resize
root@OpenstackIcehouse2:~# cat /etc/nova/nova-compute.conf [DEFAULT] compute_driver=libvirt.LibvirtD ...
- Dubbo 源码分析 - 集群容错之 Router
1. 简介 上一篇文章分析了集群容错的第一部分 -- 服务目录 Directory.服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由.上一篇文章关于服务路由相关逻辑没有 ...