当前位置: 首页 > news >正文

微型操作系统内核源码详解系列五(四):cm3下svc启动任务

系列一:微型操作系统内核源码详解系列一:rtos内核源码概论篇(以freertos为例)-CSDN博客

系列二:微型操作系统内核源码详解系列二:数据结构和对象篇(以freertos为例)-CSDN博客

系列三:微型操作系统内核源码详解系列三(0):空间存储及内存管理篇(前置篇)-CSDN博客

                微型操作系统内核源码详解系列三(1):任务及切换篇(任务函数定义)-CSDN博客

                微型操作系统内核源码详解系列三(2):任务及切换篇(任务函数定义)-CSDN博客

                微型操作系统内核源码详解系列三(3):任务及切换篇(任务函数定义)-CSDN博客

                微型操作系统内核源码详解系列三(4):arm架构篇-CSDN博客

                微型操作系统内核源码详解系列三(5):进程与线程-CSDN博客

系列四:

 ​​​​​微型操作系统内核源码详解系列四(1):操作系统调度算法(linux0.11版本内核)-CSDN博客

微型操作系统内核源码详解系列四(2):操作系统调度算法(rt-thread内核)-CSDN博客

微型操作系统内核源码详解系列四(3):操作系统调度算法(FreeRTOS内核篇上)-CSDN博客

微型操作系统内核源码详解系列四(4):操作系统调度算法(FreeRTOS内核篇下)-CSDN博客

系列五:

微型操作系统内核源码详解系列五(1):arm cortex m3架构-CSDN博客

微型操作系统内核源码详解系列五(2):cm3下栈的初始化-CSDN博客

微型操作系统内核源码详解系列五(3):cm3下调度的开启-CSDN博客

微型操作系统内核源码详解系列五(四):cm3下svc启动任务-CSDN博客

经历了前面的文章的铺垫,一切都准备就绪,接下来我们将会在SVC中断服务函数中开启第一个任务。

让我们看看SVC中断响应:

首先看前三行代码:

先令r3寄存器的值为pxCurrentTCB的地址,再把这个地址指向的内容给r1,现在r1存储的就是指针,我们知道指针就是地址,再把这个指针的值给r0,那么r0就会找到任务控制块。

pxCurrentTCB的作用是指向当前运行的任务或即将运行的任务的控制块(TCB),TCB是一个存储任务各种信息的数据结构。这三行代码的作用是获取pxCurrentTCB指向的任务栈,因为TCB的第一个成员就是栈顶指针。

现在重点来了,请看下面这行代码:

让我们先回顾一下我们在初始化stack时是如何操作的:

请读者不要误解,图中这些R代表的是这些内存地址的内容要被加载到哪个寄存器,不是寄存器在这些地方。

cm3的栈是向下增长,所以栈顶在下面。

这行代码的意思就是:从r0这个内存地址开始,把栈中往上九个地址的内容依次加载到CPU的寄存器r4-r11和r14,然后r0自增(加载后r0寄存器刚好表示这个栈里面的r0位置),也正好把portINITIAL_EXEC_RETURN加载到r14,不知道读者对这个定义还有没有印象,现在该回收伏笔了:

读者发现没有,下一行代码使用的是psp,而不是msp。看了上面的信息,我们可以推断,在把portINITIAL_EXEC_RETURN加载到r14后,如果我们进行跳转,就能成功实现从异常服务模式到线程模式的转换,那么程序就会转为使用线程堆栈,也就是说,在SVC调用结束后,我们将使用psp作为堆栈指针。

再看下一句:

现在的r0刚好对应这个栈里面的存储形参的位置(不得不说,笔者还以前怀疑过prvparameter的作用,现在发现它真的设置得非常好,虽然它并不是什么有特殊含义的参数,但是它贯穿了整个rtos架构,起到了连接和中继作用),执行任务时将会使用psp,于是我们更新psp这个栈指针。

isb是等待指令完成防止指令乱序导致缓冲区出现错误。

(这里笔者还是简单解释一下,处理器在执行指令时会使用流水线和并行这些技术,也就是说,指令并不是依次执行的,可能是同时执行的,这种方法提高了效率,但是可能导致错误的发生,于是指令集被开发时,还开发了这些特殊的指令针对那些对内存操作顺序有严格要求的操作)

这里就是清零r0寄存器,然后设置basepri寄存器为0,就是打开所有中断,basepri寄存器是一个用来控制屏蔽中断的寄存器,我们将会在临界区学习它,读者可以看看这些:

接下来看最后一行代码:

这里的意思就是异常返回时,跳转到r14代表的地址那里,前文已经提过了,在SVC调用结束后,我们将使用psp作为堆栈指针,r14存储的值的含义就是完成异常服务模式到线程模式的转换,这里就是完成转换的具体跳转指令。

这样,第一个任务就被执行了。

以上就是SVC调用的内容了,接下来笔者将会讲解PendSV中断服务,PendSV响应可以说是FreeRTOS调度器的精髓所在。

相关文章:

  • 天马学航——智慧教务系统(移动端)开发日志三
  • 用友U9-UBF自定义报表-打印模板开发学习笔记
  • SpringBoot测试实践
  • Spark SQL 血缘解析方案
  • 【Apache Doris】周FAQ集锦:第 7 期
  • python,ipython 和 jupyter notebook 之间的关系
  • 什么是N卡和A卡?有什么区别?
  • Python设计模式 - 简单工厂模式
  • Linux驱动开发笔记(十一)tty子系统及其驱动
  • AMSR/ADEOS-II L1A Raw Observation Counts V003地球表面和大气微波辐射的详细观测数据
  • 计算机组成原理笔记-第1章 计算机系统概论
  • 大疆无人机航点飞行KMZ文件提取航点坐标
  • 保存和调取得分的简易方法
  • Github 2024-06-19 C开源项目日报 Top9
  • C#面: 能够将非静态的方法覆写成静态方法吗?
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • echarts花样作死的坑
  • IDEA 插件开发入门教程
  • JavaScript创建对象的四种方式
  • Java读取Properties文件的六种方法
  • oldjun 检测网站的经验
  • Python_OOP
  • React-Native - 收藏集 - 掘金
  • web标准化(下)
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 力扣(LeetCode)357
  • 利用jquery编写加法运算验证码
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • Spring第一个helloWorld
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​Linux·i2c驱动架构​
  • #pragma once与条件编译
  • #pragma预处理命令
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (12)Hive调优——count distinct去重优化
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (7) cmake 编译C++程序(二)
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (done) 声音信号处理基础知识(2) (重点知识:pitch)(Sound Waveforms)
  • (javaweb)Http协议
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (八)Spring源码解析:Spring MVC
  • (二)hibernate配置管理
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (四)js前端开发中设计模式之工厂方法模式
  • (一)Docker基本介绍
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)原始图像数据和PDF中的图像数据
  • .form文件_SSM框架文件上传篇
  • .jks文件(JAVA KeyStore)
  • .NET C# 使用GDAL读取FileGDB要素类
  • .net core Redis 使用有序集合实现延迟队列
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .Net Core 笔试1