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

ARM Cortex-M处理器中的MSP和PSP

在ARM Cortex-M系列处理器中,MSP(主堆栈指针)和PSP(进程堆栈指针)是两种不同的堆栈指针,主要用于实现堆栈隔离和提升系统可靠性。以下是它们的核心区别和应用场景:


1. 基本定义

  • MSP(Main Stack Pointer)

    • 用途:默认堆栈指针,主要用于处理模式(Handler Mode)(如中断、异常处理)。
    • 特点:系统启动时自动初始化,所有异常处理(如中断服务例程)必须使用MSP。
    • 权限:始终在特权模式下使用。
  • PSP(Process Stack Pointer)

    • 用途:可选堆栈指针,用于**线程模式(Thread Mode)**下的应用程序代码(如用户任务)。
    • 特点:需显式配置,常见于多任务系统(如RTOS)中,每个任务拥有独立的PSP以实现堆栈隔离。
    • 权限:可在特权或非特权模式下使用(取决于配置)。

2. 操作模式与堆栈选择

Cortex-M处理器有两种执行模式:

  • 处理模式(Handler Mode)

    • 始终使用MSP
    • 触发场景:中断、异常(如SysTick、硬件错误)。
  • 线程模式(Thread Mode)

    • 可配置使用MSP或PSP,由CONTROL寄存器的SPSEL位控制:
      • SPSEL=0 → 使用MSP(默认)。
      • SPSEL=1 → 使用PSP。
    • 权限
      • 特权线程模式:可自由切换MSP/PSP。
      • 非特权线程模式:无法修改CONTROL寄存器。

3. 典型应用场景

  • 单任务系统(无RTOS)

    • 通常仅使用MSP,简单可靠。
    • 中断直接使用MSP,用户代码在线程模式下默认也使用MSP。
  • 多任务系统(RTOS)

    • PSP核心作用:每个任务分配独立堆栈,任务切换时更新PSP指向当前任务堆栈。
    • 优势
      • 任务堆栈溢出不会破坏系统关键数据(如中断上下文)。
      • 实现任务间内存隔离,提升稳定性。
    • 配置示例
      // RTOS任务切换时,更新PSP
      __set_PSP(new_task_stack_top);
      // 切换CONTROL寄存器使用PSP
      __set_CONTROL(0x03); // SPSEL=1, 切换到非特权模式(可选)
      

4. 关键寄存器与控制

  • CONTROL寄存器

    • SPSEL位(Bit 1):
      • 0 → 线程模式使用MSP。
      • 1 → 线程模式使用PSP。
    • nPRIV位(Bit 0):
      • 0 → 特权模式。
      • 1 → 非特权模式(限制某些操作)。
  • 代码中操作堆栈指针

    // 读取/设置MSP和PSP(需特权模式)
    uint32_t current_msp = __get_MSP();
    uint32_t current_psp = __get_PSP();
    __set_MSP(new_msp_value);
    __set_PSP(new_psp_value);
    

5. 总结对比

特性MSPPSP
默认使用场景处理模式(中断、异常)线程模式(用户任务)
初始化系统启动自动初始化需手动配置
多任务隔离不适用(全局共享)支持(每个任务独立堆栈)
权限要求始终特权模式可配置特权或非特权模式
典型应用裸机程序、中断服务RTOS任务、复杂多任务系统

6. 实践建议

  • 裸机开发:优先使用MSP,简化设计。
  • RTOS开发:为每个任务分配PSP,避免堆栈冲突。
  • 安全性:在非特权模式下限制PSP修改,防止用户代码破坏系统。
  • 调试:通过调试器观察MSP/PSP的值,确保任务切换时堆栈正确更新。

通过合理使用MSP和PSP,可以显著提升嵌入式系统的稳定性和可维护性,尤其是在资源受限且要求高可靠性的场景中。


好的!我尽量用「大白话」和比喻来解释,保证你一听就懂!


想象你是一个打工人

假设你有 两个记事本(堆栈):

  1. 「老板专用记事本」(MSP)

    • 用途:专门用来记老板突然扔给你的急事(比如中断、系统崩溃)。
    • 特点:必须随身携带,随时能用,而且只能你自己用(特权模式)。
    • 举个栗子
      你正在写代码(普通任务),突然老板喊你修BUG(中断),你立刻放下手头工作,掏出「老板专用记事本」记录问题,修完再回去继续写代码。
  2. 「日常任务记事本」(PSP)

    • 用途:记录你平时的工作任务(比如用户程序、普通函数)。
    • 特点:可以灵活分配,比如每个项目(任务)单独用一个记事本,避免混乱。
    • 举个栗子
      你同时做两个项目(多任务),给每个项目分配一个「日常记事本」。切换项目时,只需要换一个记事本,互相不干扰。

关键区别

  1. 「老板的事 vs 你的事」

    • MSP:处理老板的急事(中断、系统级操作),必须快速响应,优先级最高。
    • PSP:处理你自己的日常工作(普通任务),可以慢慢来。
  2. 「记事本能不能共享」

    • MSP:全公司只有一个(全局共享),谁处理急事都用它。
    • PSP:每个项目(任务)单独一个,互相隔离,一个项目搞砸了(比如堆栈溢出),不会影响其他项目。
  3. 「谁有权限用」

    • MSP:只有你(系统内核、特权模式)能修改。
    • PSP:可以分权限,比如让实习生(非特权模式)也能用,但限制他乱改。

举个实际场景

假设你在写一个智能手表的程序:

  1. MSP 的用途

    • 突然要处理「心率异常报警」(中断),系统立刻停下手表界面刷新(普通任务),用 MSP 快速保存现场,处理报警。
  2. PSP 的用途

    • 平时同时运行「计步器」和「天气显示」两个任务,每个任务用自己的 PSP 堆栈。
    • 如果计步器的代码写错了(堆栈溢出),只会搞坏自己的 PSP,不会影响天气显示和 MSP(系统不会崩溃)。

一句话总结

  • MSP:系统「紧急专用通道」,处理中断和异常,全局唯一,必须可靠。
  • PSP:你的「多任务分身术」,每个任务独立堆栈,互不干扰。

再打个比方:

  • MSP 像医院的急诊室,随时处理紧急情况,全院只有一间。
  • PSP 像普通门诊,每个科室(任务)一间,病人(数据)分开排队,不会挤爆急诊室。

在嵌入式开发中,是否要关心 MSPPSP,取决于你的角色、开发场景和系统复杂度。用大白话分情况说明:


1. 如果你是写业务代码的「应用层开发人员」

  • 大多数情况下不需要关心,尤其是:

    • 用RTOS(如FreeRTOS、uCOS)
      RTOS已经帮你管理好了任务堆栈(用PSP),你只需要写任务函数,分配堆栈大小,完全不用手动操作PSP/MSP。
      // 例子:在FreeRTOS中创建任务,你只需指定堆栈大小,不用碰PSP
      xTaskCreate(task_function, "Task1", 512, NULL, 1, NULL);
      
    • 裸机开发但代码简单
      如果只是单任务循环(比如顺序执行初始化→采集数据→显示→延时),系统默认用MSP,你甚至不知道PSP的存在。
  • 需要关心的例外情况

    • 调试堆栈溢出问题
      如果程序崩溃,可能需要查看MSP/PSP指向的堆栈区域是否被写爆。
    • 写底层库或驱动
      如果你要写和中断、任务切换相关的底层代码(比如自定义调度器),需要理解MSP/PSP的切换逻辑。

2. 如果你是「系统工程师」或「内核开发者」

  • 必须深刻理解MSP/PSP,因为:
    • 任务切换
      在RTOS中切换任务时,需要保存当前任务的PSP,并加载新任务的PSP。
      ; 伪代码:任务切换的核心操作
      Save当前任务的寄存器到它的PSP堆栈;
      Load新任务的PSP值到CPU;
      从新任务的PSP堆栈恢复寄存器;
      
    • 中断处理
      系统默认用MSP处理中断,但某些高性能场景可能优化为用PSP(需谨慎)。
    • 安全隔离
      在需要权限隔离的系统(如非特权模式运行用户代码),需通过PSP限制任务对系统堆栈的访问。

3. 一句话总结

  • 业务层开发人员
    不用直接操作MSP/PSP,就当它们不存在,除非你要解决某些“玄学”崩溃问题。
    (就像开燃油车不用懂内燃机原理,但漏油了得知道去修)

  • 系统层开发人员
    必须掌握MSP/PSP,这是实现多任务、中断、内存隔离的核心机制。
    (就像赛车工程师必须懂发动机每个零件)


4. 举个实际例子

场景:你正在用STM32和FreeRTOS写一个智能家居控制器
  • 业务代码(你写的部分)

    void TemperatureTask(void *pvParameters) {while(1) {float temp = read_sensor();  // 读传感器send_to_display(temp);       // 发送到显示屏vTaskDelay(1000);            // 等1秒}
    }
    
    • 完全不用碰MSP/PSP,只需关注业务逻辑和任务堆栈大小(比如configMINIMAL_STACK_SIZE)。
  • 系统层(RTOS内部)

    // RTOS内核在切换任务时的隐藏操作:
    void vTaskSwitchContext() {// 保存旧任务的PSP到它的任务控制块(TCB)old_task->psp = __get_PSP();// 从新任务的TCB加载PSP__set_PSP(new_task->psp);
    }
    
    • 这里必须操作PSP,但你作为业务开发者看不到这些代码。

5. 什么情况下你会被迫了解MSP/PSP?

  • 调试时发现神秘崩溃
    比如日志显示HardFault_Handler,检查发现某个任务的PSP指向了非法地址。
  • 优化特殊场景性能
    比如在高频中断中,为了减少堆栈切换开销,刻意让中断共享PSP(需极度小心!)。
  • 自己造轮子写RTOS
    恭喜你,从此MSP/PSP会刻进你的DNA里。

6. 最终建议

  • 新手:
    先当MSP/PSP不存在,专注于业务逻辑。等遇到崩溃问题或学习RTOS原理时,再回头理解它们。

  • 进阶:
    通过调试器观察MSP/PSP的值(如下所示),加深对堆栈和任务切换的理解:
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    (图中:在Keil调试器中查看寄存器的MSP和PSP值)

  • 记住:
    MSP/PSP是CPU的“幕后工作人员”,99%的时间它们默默工作,只有1%的时间(出问题时)需要你喊它们出来对质。 😉

相关文章:

ARM Cortex-M处理器中的MSP和PSP

在ARM Cortex-M系列处理器中,MSP(主堆栈指针)和PSP(进程堆栈指针)是两种不同的堆栈指针,主要用于实现堆栈隔离和提升系统可靠性。以下是它们的核心区别和应用场景: 1. 基本定义 MSP(…...

《Keras 3 使用 NeRF 进行 3D 体积渲染》:此文为AI自动翻译

《Keras 3 使用 NeRF 进行 3D 体积渲染》 作者: Aritra Roy Gosthipaty, Ritwik Raha 创建日期: 2021/08/09 最后修改时间: 2023/11/13 描述: 体积渲染的最小实现,如 NeRF 中所示。 (i) 此示例使用 Keras 3 在 Colab 中查看 GitHub 源 介绍 在此示例中,我们展示了…...

Pytorch实现之浑浊水下图像增强

简介 简介:这也是一篇非常适合GAN小白们上手的架构文章!提出了一种基于GAN的水下图像增强网络。这种网络与其他架构类似,生成器是卷积+激活函数+归一化+残差结构的组成,鉴别器是卷积+激活函数+归一化以及全连接层。损失函数是常用的均方误差、感知损失和对抗损失三部分。 …...

【redis】数据类型之Bitfields

Redis的Bitfields(位域)与Bitmaps一样,在Redis中并不是一种独立的数据类型,而是一种基于字符串的数据结构,用于处理位级别的操作。允许用户将一个Redis字符串视作由一系列二进制位组成的数组,并对这些位进行…...

Python入门 — 类

面向对象编程中,编写表示现实世界中的事物和情景的类(class),并基于这些类来创建对象(object)。根据类来创建对象称为实例化,这样就可以使用类的实例(instance) 一、创建…...

R-INLA实现绿地与狐狸寄生虫数据空间建模:含BYM、SPDE模型及PC先验应用可视化...

全文链接:https://tecdat.cn/?p40720 本论文旨在为对空间建模感兴趣的研究人员客户提供使用R-INLA进行空间数据建模的基础教程。通过对区域数据和地统计(标记点)数据的分析,介绍了如何拟合简单模型、构建和运行更复杂的空间模型&…...

Linux云计算SRE-第十五周

1.总结Dockerfile的指令和Docker的网络模式 一、Dockerfile 核心指令详解 1、基础构建指令 指令 功能描述 关键特性 FROM 指定基础镜像(必须为首条指令) - 支持多阶段构建:FROM node AS builder - scratch 表示空镜像 RUN 在镜像构建…...

2014年下半年试题一:论软件需求管理

论文库链接:系统架构设计师论文 论文题目 软件需求管理是一个对系统需求变更了解和控制的过程。需求管理过程与需求开发过程相互关联,初始需求导出的同时就要形成需求管理规划,一旦启动了软件开发过程需求管理活动就紧密相伴。 需求管理过程中…...

podman加速器配置,harbor镜像仓库部署

Docker加速器 registries加速器 [rootlocalhost ~]# cat /etc/redhat-release CentOS Stream release 8 [rootlocalhost ~]# cd /etc/containers/ [rootlocalhost containers]# ls certs.d policy.json registries.conf.d storage.conf oci registries.conf re…...

信息学奥赛一本通 1522:网络 | OpenJudge 百练 1144:Network

【题目链接】 ybt 1522:网络 OpenJudge 百练 1144:Network 【题目考点】 1. 图论:割点 【解题思路】 每个交换机是一个顶点,如果两地点之间有电话线连接,那么两顶点之间有一条无向边,该图是无向图。 初始时任何地…...

本地部署DeepSeek的硬件配置建议

本地部署DeepSeek的硬件配置需求因模型参数规模和部署工具不同而有所差异,以下是综合多个来源的详细要求: 1. 基础配置(适用于7B参数模型) 内存:最低8GB,推荐16GB及以上;若使用Ollama工具&…...

Redis面试题----Redis 的持久化机制是什么?各自的优缺点?

Redis 提供了两种主要的持久化机制,分别是 RDB(Redis Database)和 AOF(Append Only File),下面将详细介绍它们的原理、优缺点。 RDB(Redis Database) 原理 RDB 持久化是将 Redis 在某个时间点上的数据集快照以二进制文件的形式保存到磁盘上。可以通过手动执行 SAVE …...

C#实现本地AI聊天功能(Deepseek R1及其他模型)。

前言 1、C#实现本地AI聊天功能 WPFOllamaSharpe实现本地聊天功能,可以选择使用Deepseek 及其他模型。 2、此程序默认你已经安装好了Ollama。 在运行前需要线安装好Ollama,如何安装请自行搜索 Ollama下载地址: https://ollama.org.cn Ollama模型下载地址&#xf…...

Metal 学习笔记四:顶点函数

到目前为止,您已经完成了 3D 模型和图形管道。现在,是时候看看 Metal 中两个可编程阶段中的第一个阶段,即顶点阶段,更具体地说,是顶点函数。 着色器函数 定义着色器函数时,可以为其指定一个属性。您将在本…...

C# string转unicode字符

在 C# 中,将字符串转换为 Unicode 字符(即每个字符的 Unicode 码点)可以通过遍历字符串中的每个字符并获取其 Unicode 值来实现。Unicode 值是一个整数,表示字符在 Unicode 标准中的唯一编号。 以下是实现方法: 1. 获…...

HITCON2017SSRFME-学习复盘

代码审计 192.168.122.15 <?phpif (isset($_SERVER[HTTP_X_FORWARDED_FOR])) {$http_x_headers explode(,, $_SERVER[HTTP_X_FORWARDED_FOR]);//用逗号分割多个IP$_SERVER[REMOTE_ADDR] $http_x_headers[0];}echo $_SERVER["REMOTE_ADDR"];//给第一个IP发送请…...

【Http和Https区别】

概念&#xff1a; 一、Http协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档&#xff08;如HTML&#xff09;的应用层协议&#xff0c;主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议&#xff0c;客户端通常…...

2025数学建模竞赛汇总,错过再等一年

01、2025第十届数维杯大学生数学建模挑战赛&#xff08;小国赛&#xff09; 竞赛介绍&#xff1a;数学建模行业内仅次于国赛和美赛的的第三赛事&#xff0c;被多所高校认定为国家级二类竞赛。赛题类型是国内唯一和高教社杯国赛题型风格完全一致的全国性数学建模竞赛&#xff0…...

基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘 要 《计算机网络》题库管理系统是一种新颖的考试管理模式&#xff0c;因为系统是用Java技术进行开发。系统分为三个用户进行登录并操作&#xff0c;分别是管理员、教师和学生。教师在系统后台新增试题和试卷&#xff0c;学生进行在线考试&#xff0c;还能对考生记录、错题…...

ReentrantLock 用法与源码剖析笔记

&#x1f4d2; ReentrantLock 用法与源码剖析笔记 &#x1f680; 一、ReentrantLock 核心特性 &#x1f504; 可重入性&#xff1a;同一线程可重复获取锁&#xff08;最大递归次数为 Integer.MAX_VALUE&#xff09;&#x1f527; 公平性&#xff1a;支持公平锁&#xff08;按等…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...