μ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之间是如何同步的,以及这 ...
随机推荐
- python csv读写
https://blog.csdn.net/taotiezhengfeng/article/details/75577998
- 服务器windows2008系统登录报错:由于远程桌面服务当前正忙,因此无法完成您尝试的任务。请在...
1.问题描述:windows server 2008服务器通过远程桌面登录时很慢,登录不进去,把远程桌面关掉后,再用远程桌面登录时,出现下图提示. 把服务器接上显示器键盘鼠标后,卡在系统登录的欢迎界面 ...
- Dubbo 源码分析 - 自适应拓展原理
1.原理 我在上一篇文章中分析了 Dubbo 的 SPI 机制,Dubbo SPI 是 Dubbo 框架的核心.Dubbo 中的很多拓展都是通过 SPI 机制进行加载的,比如 Protocol.Clu ...
- 【设计经验】2、ISE中ChipScope使用教程
一.软件与硬件平台 软件平台: 操作系统:Windows 8.1 开发套件:ISE14.7 硬件平台: FPGA型号:XC6SLX45-CSG324 二.ChipScope介绍 ChipScope是X ...
- python爬虫学习之Scrapy框架的工作原理
一.Scrapy简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网 ...
- Android NDK学习(一):目录结构解析
我们配置好NDK环境后,基本可以看到其目录结构如下图: 下面我们来分析一下NDK根目录的结构: ndk-build:该Shell脚本是Android NDK构建系统的起始点,一般在项目中仅仅执行这一个 ...
- Python学习笔记【第十篇】:Python面向对象进阶
保护对象的属性 如果有一个对象,当需要对其进行修改属性时,有2种方法 对象名.属性名 = 数据 ---->直接修改 对象名.方法名() ---->间接修改 为了更好的保存属性安全,即不能随 ...
- 【Windows】Git自动拉取
原文:https://blog.csdn.net/qq_38375394/article/details/80093003 bat脚本.windows的schtasks,也就是类似于linux的cro ...
- Oracle SQL调优记录
目录 一.前言 二.注意点 三.Oracle执行计划 四.调优记录 @ 一.前言 本博客只记录工作中的一次oracle sql调优记录,因为数据量过多导致的查询缓慢,一方面是因为业务太过繁杂,关联了太 ...
- 简单聊一聊那些svg的沿路径运动
之前遇见动画就很想用css实现,显然有些效果是我们力所不能及,实现起来麻烦,效果不好,让人捉急.其实归结起来,不同的动画有自己的优势,根据实际情况进行取舍.本文就告诉大家如何用SVG写出个简单动画.就 ...