μ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之间是如何同步的,以及这 ...
随机推荐
- 消除blur属性的边框
直接设置样式为: outline:none <!DOCTYPE html> <html lang="en"> <head> <meta ...
- cvb源码分析,resful规范,drf,drf序列化组件,95
1 CBV的源码分析 -Class Base View(基于类的视图) -Function Base View(基于函数的视图) -def as_view 类方法 -def view:类方法内部,闭包 ...
- STM32CubeMX的串口配置,以及驱动代码
1.STM32CubeMX的配置没啥子好说的,使能然后改一下波特率和字长,然后在将中断勾选,把中断等级调到1(一定要比systick的优先级垃圾!!!) 2.驱动代码 在生成的it.c文件中,例如用的 ...
- 【repost】 JS变量重复声明以及忽略var 声明的问题及其背后的原理
JS的容错率很高,一些其他语言常见的小错误JS都能大度得包容,比如给一个方法传入超出预计的参数.在声明变量之前使用该变量(变量的声明提升解决了这个问题)等等,这里我们就要解剖一下JS变量重复声明以及当 ...
- 如果解决小程序1024kb渲染之坑
问题: 在小程序开发中如果有那么个场景和操作步骤,获取商品下拉列表商品列表data为goodsList 当从后台获取数据response.data.list,通常我们会setData({goodsLi ...
- roadhog如何支持除development和production外的其他环境变量配置
roadhog的build和start脚本分别对应了env/development和production,但实践中存在第三种开发环境(可能是预发或集成测试),配置和前两种也都不一样,但现在似乎没办法支 ...
- 在已有数据的表中添加id字段并且自增
各位大牛,小弟在开发过程中,遇到了这样一个问题,由于新功能的增加需要使原有的一张表的结构作出调整,需要添加一个id主键字段,但是因为表里有很多数据了,所以,怎样才能添加这个字段,并且使原有的数据也能够 ...
- Java中基本数据和包装类的比较
public class AutoBoxTest { public static void main(String[] args) { Integer a1 = 127; Integer a2 = 1 ...
- 吴恩达机器学习笔记14-逻辑回归(Logistic Regression)
在分类问题中,你要预测的变量
- Node.js(day2)
一.使用Node实现基本Apache的功能 在上一篇笔记中,我们提到如果打开一个文件需要进行一次url判断是繁琐的,我们希望我们的Node具有类似Apache这种web服务器的一个功能:将文件放到ww ...