ARM Cortex-M内核中系统堆栈

文章目录

  • 有无OS的栈结构区别:
    • 裸机的任务栈结构
    • 带FreeRTOS操作系统的任务栈
  • ARM的寄存器有哪些
    • 特殊寄存器有哪些
  • 关于FreeRTOS中的SP寄存器
  • 栈操作【压栈与弹栈的操作】
  • 一般函数嵌套调用时sp指针的变化
  • Cortex-M内核的MSP与PSP作用

有无OS的栈结构区别:

裸机的任务栈结构

无OS的堆栈结构:此时每个任务的堆栈都在一起
在这里插入图片描述

带FreeRTOS操作系统的任务栈

在FreeRTOS中对线程、进程没有明显区分,统一称为任务。

有OS的堆栈结构:每个任务都有独立栈空间,用于保存上下文信息和全局变量

在这里插入图片描述

ARM的寄存器有哪些

ARM 架构的寄存器可以分为以下几类:

  • 通用寄存器:ARM 架构有 17 个 32 位的通用寄存器,它们命名为 R0-R15,其中 R13-R15 被用作栈指针、链接寄存器(LR)和程序计数器(PC)。

  • 状态寄存器:也称为程序状态寄存器(PSR),用于存储当前处理器的状态信息,例如条件码、中断使能位等。

  • 特殊寄存器:包括控制寄存器、处理器 ID 寄存器、系统控制寄存器等,它们用于控制处理器的一些重要行为和特性。

  • 浮点寄存器:ARMv7 架构引入了 VFP 协处理器,增加了 32 个浮点寄存器(S0-S31),可用于高精度浮点运算。

特殊寄存器有哪些

特殊寄存器是指在 ARM 架构中具有特殊用途的寄存器,包括以下几个:

  1. 控制寄存器(Control Register):用于控制处理器的一些重要行为和特性,如异常处理、缓存设置等。

  2. 处理器 ID 寄存器(Processor ID Register):用于标识处理器的类型和版本信息。

  3. 系统控制寄存器(System Control Register):用于控制系统级的功能和特性,如内存管理单元(MMU)的设置、缓存控制等。

  4. 中断控制寄存器(Interrupt Control Register):用于控制中断的使能和屏蔽,包括中断优先级、中断屏蔽位等。

  5. 定时器控制寄存器(Timer Control Register):用于控制定时器的计数和触发方式,包括定时器的频率、计数模式等。

  6. 异常控制寄存器(Exception Control Register):用于控制异常处理和异常向量表的地址。

这些特殊寄存器在 ARM 架构中扮演着关键的角色,可以控制和配置处理器的各种功能和特性,用于实现更高级的操作和控制。

关于FreeRTOS中的SP寄存器

一般来说Cortex-M系列有两种工作模式:

  • Thread Mode (线程模式):程序按照编译好的代码顺序执行

  • ​Handler Mode(中断模式):收到中断信号并执行中断处理函数

所以,Cortex-M系列内核使用了双堆栈,即MSP和PSP

  • MSP : Main_Stack_Pointer 主栈
  • PSP : Process_Stack_Pointer 任务栈
  • SP : 堆栈指针,指向最后一个被压入元素的地址

R13在任何时刻只能是其中一个,默认情况为MSP,可以通过控制寄存器:CONTROL寄存器的bit1来改变。
在这里插入图片描述

关于MSP和PSP的选用,其是通过CONTORL寄存器来配置,仅在Thread Mode下才可设置CONTORL寄存器。一般情况下,没有必要使用PSP,除非是有os存在时,MSP用于os内核的sp,而PSP用于thread级app的sp,这两个sp需严格分开。

在编译器中,可以通过r13(R13)或sp(SP)来访问堆栈(具体是MSP和PSP由当时环境决定);也可以通过指定的MRS、MSR指令来访问MSP和PSP。

在这里插入图片描述

控制寄存器有两个用途,其一用于定义特权级别,其二用于选择当前使用哪个堆栈指针。由两个比特来行使这两个职能。

在这里插入图片描述
在裸机开发中,CONTROL的bit1始终是0,也就是说裸机开发中全程使用程MSP,并没有使用PSP。在执行后台程序(大循环程序)SP使用的是MSP,在执行前台程序(中断服务程序)SP使用的是MSP

在OS开发中,当运行中断服务程序的时候CONTROL的bit1是0,SP使用的是MSP;当运行线程程序的时候CONTROL的bit1是1,SP使用的是PSP。MSP是系统复位后(即其处于Handler Mode)的指定sp(vector table的前4Byte自动载入),用于处理异常中断。当结束Reset_Handler后,cpu进入正常运行状态(即其处于Thread Mode),仅在此状态下PSP才能被使用,当然MSP也可以使用。其后如有硬中断来临,则进入Handler Mode,如果硬件中断结束,则返回Thread Mode。

栈操作【压栈与弹栈的操作】

Cortex-M0中堆栈方向是向低地址方向增长,为满堆栈机制。堆栈操作是通过PUSH和POP来完成操作的。实际上,除了POP指令可以从栈顶中取数据外;MOV指令也可从任意位置取数据,但不会影响栈结构(即不影响其sp)

压栈与弹栈的操作:

  • 压栈:SP先自减4,然后将待压入的数据存放到SP所指的地址
  • 弹栈:从SP指针所指的地址读出数据,然后SP指针自增4

一般函数嵌套调用时sp指针的变化

在普通的函数嵌套调用中,当一个函数调用另一个函数时,程序会将当前函数的执行现场(包括 PC(程序计数器)、当前函数的状态、参数、返回地址等)保存在当前函数的栈帧中。接着,将栈指针 SP(stack pointer)移动到新的栈帧的栈顶位置(一般是上一个栈帧的底部位置),然后继续执行被调用的函数。

在这个过程中,SP 指针的变化如下:

  1. 进入被调用函数前:将当前函数的执行现场保存在当前函数的栈帧中,SP 指针不变。

  2. 进入被调用函数时:将新的栈帧的起始位置指定为上一个栈帧的底部,这个位置需要根据前一个栈帧的大小确定,即 SP 指针移动到新的栈帧的底部位置。

  3. 执行被调用函数时:如果有局部变量,则将这些变量分配在新的栈帧中。此时,SP 指针可能会进一步移动到这些变量的内存起始位置。

  4. 返回到调用函数时:将被调用函数的返回值或状态存储在新的栈帧中,并且将 SP 指针恢复到上一个栈帧的底部位置,以便取出当前函数的执行现场,同时恢复上一个栈帧中的现场并继续执行。

需要注意的是,在函数嵌套调用过程中,递归调用、多层嵌套和异常处理等情况会使 SP 指针的变化更加复杂。因此,在编写和调试程序时,需要仔细注意栈帧的大小、内存分配和释放以及异常处理等问题,以确保程序的正确性和稳定性。

Cortex-M内核的MSP与PSP作用

首先,设立双指针是为了保证OS的安全性和稳健性。通常来说,操作系统和异常事件(中断或其他fault)使用MSP,用户程序(线程)使用PSP。MSP与PSP指针之间的切换会在处理异常事件时自动完成。

本质上,区别于用户程序使用PSP,操作系统和异常事件单独使用一个MSP指针的目的,是为了保证栈数据不会被用户程序意外访问或栈空间被用户程序占用。比如,当应用程序发生栈溢出问题时,必须要确保应用程序的故障不会影响到操作系统的运行和异常事件的处理——也就需要保证始终要有栈空间来执行异常事件。

裸机操作时,使用的就是MSP指针。其实OS在上电复位到切换线程之前用的都是MSP指针,也就是线程切换之前都是一个裸机程序的状态。

参考博文:
关于FreeRTOS的底层实现和基础认识

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/140832.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【List篇】LinkedList 详解

目录 成员变量属性构造方法add(), 插入节点方法remove(), 删除元素方法set(), 修改节点元素方法get(), 取元素方法ArrayList 与 LinkedList的区别Java中的LinkedList是一种实现了List接口的 双向链表数据结构。链表是由一系列 节点(Node)组成的,每个节点包含了指向 上一个…

第9章 【MySQL】InnoDB的表空间

表空间 是一个抽象的概念,对于系统表空间来说,对应着文件系统中一个或多个实际文件;对于每个独立表空间来说,对应着文件系统中一个名为 表名.ibd 的实际文件。大家可以把表空间想象成被切分为许许多多个 页 的池子,当我…

队列(JAVA)

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的性质。 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 在JAVA中队列和栈不同Stack是一个类&a…

线性代数的本质——几何角度理解

B站网课来自 3Blue1Brown的翻译版,看完醍醐灌顶,强烈推荐: 线性代数的本质 本课程从几何的角度翻译了线代中各种核心的概念及性质,对做题和练习效果有实质性的提高,下面博主来总结一下自己的理解 1.向量的本质 在物…

ElasticSearch(二)

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,…

Hadoop的HDFS高可用方案

一、Hadoop高可用简介 Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但 HDFSNameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多,所以它的实现也更加复杂 1、HDFS系统高可用简介…

uniapp 离线打包 plus.runtime.install 安装页面不弹起

uniapp 离线打包 plus.runtime.install 安装页面不弹起 updateVersion(webview : any, eventTitle : string, eventContent : string) {const loading plus.nativeUI.showWaiting(准备下载);var dtask plus.downloader.createDownload(eventContent,{method: GET,timeout: 5…

Linux:文本搜索命令grep

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html grep是类Unix系统中用于搜索并打印文件中符合某种模式(pattern)的行。grep命令的的基本语法如下所示: grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [F…

无需root,删除安卓内置应用

今天在家里反到一台比较老的安卓手机,直接恢复出厂设置,开机后一堆自带的应用,卡的一匹,于是就想办法把内置软件卸载掉。 1、手机开启开发者模式,打开usb调试。 2、手机与安卓连接,然后执行adb devices&a…

Minecraft 1.20.x Forge模组开发 06.建筑生成

我们本次尝试在主世界生成一个自定义的建筑。 效果展示 效果展示 效果展示 由于版本更新缘故,1.20的建筑生成将不涉及任何Java包的代码编写,只需要在数据包中对建筑生成进行自定义。 1.首先我们要使用游戏中的结构方块制作一个建筑,结构方块使用教程参考1.16.5自定义建筑生…

机器学习——pca降维/交叉验证/网格交叉验证

1、pca降维:目的是提升模型训练速度 定义: 使用方法:给训练数据或者测试数据进行降维处理 给训练数据降维 给测试数据降维:这里1就要用transform,而不是fit_transform,因为之前训练数据降维时特征已经确定…

JimuReport积木报表 v1.6.2 版本正式发布—开源免费的低代码报表

项目介绍 一款免费的数据可视化报表,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等! Web 版报表设计器,类似于excel操作风格,通过拖拽完成报…

基于SpringBoot的墙绘产品展示交易平台设计与实现

目录 前言 一、技术栈 二、系统功能介绍 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本墙绘产…

IMX6ULL ARM Linux开发板SD卡启动,SD卡的分区与分区格式化创建

一、确定TF卡挂载到ubuntu上的设备名称及分区情况 1. 在ubuntu不接入TF卡的情况下, 使用df -lh /dev/sd*命令查看当前"/dev/sd开头"的设备。 ##输入df -lh /dev/sd*命令,敲回车键 ~$ df -lh /dev/sd* 2.将TF卡接入到ubuntu,再次使…

使用Kalibr工具线对相机+IMU离线标定

传感器标定的准确后面做算法才会更准确,所以对Kalibr进行学习。 一、Kalibr编译 1、下载kalibr包 GitHub下载地址 2、 解压后放到/catkin_ws/src文件夹下 重新命令文件夹为kalibr 3、 安装依赖库 sudo apt-get install python-setuptools python-rosinstall…

你写过的最蠢的代码是?

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

驱动开发练习,platform驱动模型的使用

一.总线模型介绍 linux中将一个挂载在总线上的驱动的驱动模型分为三部分:device、driver和bus; device部分:用来保存设备信息对象,在内核中一个klist_device链表中进行管理; driver部分:用来保存驱动信息对…

爬虫 — 验证码反爬

目录 一、超级鹰二、图片验证模拟登录1、页面分析1.1、模拟用户正常登录流程1.2、识别图片里面的文字 2、代码实现 三、滑块模拟登录1、页面分析2、代码实现(通过对比像素获取缺口位置) 四、openCV1、简介2、代码3、案例 五、selenium 反爬六、百度智能云…

云计算与大数据——部署Hadoop集群并运行MapReduce集群(超级详细!)

云计算与大数据——部署Hadoop集群并运行MapReduce集群(超级详细!) Linux搭建Hadoop集群(CentOS7hadoop3.2.0JDK1.8Mapreduce完全分布式集群) 本文章所用到的版本号: CentOS7 Hadoop3.2.0 JDK1.8 基本概念及重要性 很多小伙伴部署集群用hadoop用mapr…