μC/OS-II 要点分析 ------ PendSV_Handler
首先贴出今天要与大家分享的内容源码(位于内核源码的 os_cpu_a.asm 中):
PendSV_Handler
CPSID I
MRS R0, PSP
CBZ R0, PendSV_Handler_Nosave
SUBS R0, R0, #0x20
STM R0, {R4-R11}
LDR R1, =OSTCBCur
LDR R1, [R1]
STR R0, [R1]
PendSV_Handler_Nosave
PUSH {R14}
LDR R0, =OSTaskSwHook
BLX R0
POP {R14}
LDR R0, =OSPrioCur
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCur
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2]
LDM R0, {R4-R11}
ADDS R0, R0, #0x20
MSR PSP, R0
ORR LR, LR, #0x04
CPSIE I
BX LR
这两段代码尤为重要,内核中任务的切换主要就是由它们实现的。接下来,我将逐行为大家解析其中的奥秘。
这两段代码是中断服务程序(ISR),那么由谁来触发中断呢?我们以OSCtxSw()这个函数为入手点。
它其实就是C程序中的OS_TASK_SW()
#define OS_TASK_SW() OSCtxSw()
开始分析OSCtxSw()
OSCtxSw
PUSH {R4, R5}
LDR R4, =NVIC_INT_CTRL
LDR R5, =NVIC_PENDSVSET
STR R5, [R4]
POP {R4, R5}
BX LR
1.首先进入函数,将R4,R5入栈,保护寄存器。
2.给R4,R5分别赋值,文件中这样定义:
NVIC_INT_CTRL EQU 0xE000ED04
NVIC_PENDSVSET EQU 0x10000000
NVIC_INT_CTRL为中断控制寄存器的地址,NVIC_PENDSVSET为PendSV中断的触发值
3.将触发值写入控制寄存器
4.弹出R4,R5
因为我们一般调用任务切换的时候,都是在临界区调用(禁止中断),所以不会产生中断。之后调用OS_EXIT_CRITICAL()函数退出临界区后,中断才会发生,这样就产生了PendSV异常。
接下来才是我们的重点,开始分析ISR!
CPSID I
#关中断,防止切换任务期间被打扰
MRS R0, PSP
#取出PSP(程序栈指针)赋值给R0
CBZ R0, PendSV_Handler_Nosave
#若R0为0,则跳转到PendSV_Handler_Nosave函数继续执行,这里我们讲述的就是由延时导致的任务切换,PSP都是有值的,所以继续执行
SUBS R0, R0, #0x20
#将R0 - 0x20 则R0与PSP之间空出8个单位(每个单位4个字节)
STM R0, {R4-R11}
#将寄存器的R4-R11存入空出的8个单位
LDR R1, =OSTCBCur
#将当前TCB的地址赋给R1
LDR R1, [R1]
#取出地址处的数据(即OSTCBCur->SP的地址,因为OSTCB结构体的第一个数据就是SP)赋给R1
STR R0, [R1]
#将R0(栈顶数据的地址)赋值给OSTCBCur->SP,则OSTCBCur->SP与R0指向的位置相同
!!这段程序的OSTCBCur指的都是old_task的指针
这段程序的图解:

PUSH {R14}
LDR R0, =OSTaskSwHook
BLX R0
POP {R14}
#这小段代码就是执行OSTaskSwHook这个C的函数
LDR R0, =OSPrioCur
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
#这小段代码就将OSPrioHighRdy赋给OSPrioCur
LDR R0, =OSTCBCur
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
#这小段代码就将OSTCBHighRdy->SP赋给OSPrioCur->SP
LDR R0, [R2]
#将OSTCBHighRdy->SP的值(指向新任务栈中的地址,也就是新任务的栈顶)赋值给R0
LDM R0, {R4-R11}
#以R0为基址,读出8个单位的数据给CPU的寄存器
ADDS R0, R0, #0x20
#R0地址 + 0x20,指向几个重要的寄存器值(当前栈顶)
MSR PSP, R0
#将当前R0的值赋值给PSP
ORR LR, LR, #0x04
#确保异常返回后,新任务使用PSP指针
CPSIE I
#开启中断
!!这段程序的OSTCBCur指的都是new_task的指针
这段程序的图解:

这样也就完成了old_task到new_task的切换!
μC/OS-II 要点分析 ------ PendSV_Handler的更多相关文章
- 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的开发流程. 第一步:建 ...
- [Spark性能调优] 第一章:性能调优的本质、Spark资源使用原理和调优要点分析
本課主題 大数据性能调优的本质 Spark 性能调优要点分析 Spark 资源使用原理流程 Spark 资源调优最佳实战 Spark 更高性能的算子 引言 我们谈大数据性能调优,到底在谈什么,它的本质 ...
- 【原创】uC/OS II 任务切换原理
今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引 ...
- spark 性能调优(一) 性能调优的本质、spark资源使用原理、调优要点分析
转载:http://www.cnblogs.com/jcchoiling/p/6440709.html 一.大数据性能调优的本质 编程的时候发现一个惊人的规律,软件是不存在的!所有编程高手级别的人无论 ...
- 性能调优的本质、Spark资源使用原理和调优要点分析
本课主题 大数据性能调优的本质 Spark 性能调优要点分析 Spark 资源使用原理流程 Spark 资源调优最佳实战 Spark 更高性能的算子 引言 我们谈大数据性能调优,到底在谈什么,它的本质 ...
- AS3和js相互通信要点分析
目标:在html页面里可以使用事件来影响到swf文件的内容,swf文件也可以影响html里js代码的内容 一.新建flash文件,用Flash CC试用版新建一个TextArea.fla的源文件,不添 ...
- 混合事务分析处理“HTAP”的技术要点分析
HTAP是近些年来比较火的一个概念,本文将聊聊HTAP的前世今生及技术特点. 一.数据应用类别 根据数据的使用特征,可简单做如下划分.在选择技术平台之前,我们需要做好这样的定位. 1.1 OLTP 联 ...
- Java 8 中 ConcurrentHashMap工作原理的要点分析
简介: 本文主要介绍Java8中的并发容器ConcurrentHashMap的工作原理,和其它文章不同的是,本文重点分析了对不同线程的各类并发操作如get,put,remove之间是如何同步的,以及这 ...
随机推荐
- 关闭iptables服务及命令行连接wifi及locale设置
Ubuntu系统启动时都会自动启动iptables服务.如果想关闭该服务的自动启动,可以执行: sudo ufw disable 命令行方式连接某个SSID: sudo nmcli d wifi co ...
- Docker优势以及与传统虚拟机对比(1)
docker优势 1.更快速地交付和部署: 2.更高的虚拟化(不需要额外的hypervisor支持,是内核级的虚拟化,实现更高的性能呢和效率): 3.更轻松的迁移和扩展: 4.更简单的管理 与传统的 ...
- scrollIntoView() 调用元素就可以出现在视窗中
/* 如果滚动页面也是DOM没有解决的一个问题.为了解决这个问题,浏览器实现了一下方法, 以方便开发人员如何更好的控制页面的滚动.在各种专有方法中,HTML5选择了scrollIntoView() 作 ...
- IntelliJ IDEA的main方法,for循环,syso的快捷键
原文链接:http://blog.csdn.net/tiantiandjava/article/details/42269173 今天偶然发现了IntelliJ中 创建main函数的快捷键,依次还有f ...
- Python爬取淘宝店铺和评论
1 安装开发需要的一些库 (1) 安装mysql 的驱动:在Windows上按win+r输入cmd打开命令行,输入命令pip install pymysql,回车即可. (2) 安装自动化测试的驱动s ...
- La nuova tecnologia del puntatore laser
Il potente puntatore laser 20000 mW viene fornito di serie con gestione termica e driver laser di qu ...
- spring 排除指定的类或者包扫描
<!-- 排除Controller注解的扫描 --> <context:component-scan base-package="exampleBean"> ...
- Openvswitch手册(5): VLAN and Bonding
我们这一节来看Port 一般来说一个Port就是一个Interface,当然也有一个Port对应多个Interface的情况,成为Bond VLAN Configuration Port的一个重要的方 ...
- vue-router的history模式发布配置
如果你正在尝试将基于vue-router的项目部署到windows中,希望本文能够有所帮助. iis配置 无需安装其他组件,将错误页指向index.html即可 <?xml version=&q ...
- CSS实现div高度自适应
1.有时候,我们希望容器有一个固定高度,但当其中的内容多的时候,又希望高度能够自适应,也即容器在纵向能被撑开,且如果有背景,也能够自适应.在一般情况下,使用min-height即可解决.但是广大网民的 ...