使用过cortex-M4内核单片机的朋友对下面这张图一定不会感到陌生,它是ST原厂手册里面的memory map,里面的信息量其实非常多,今天简单说明一部分。

我们在编写stm32代码的时候最长使用的地址有两块,第一块是0x0000 0000~0x3FFF FFFF,

第二块是0x4000 0000~0x5003 FFFF。注意,第二块地址是我们APB与AHB总线上面挂载着的各种外设的物理地址,我们想要操作外设就是配置这些寄存器地址。我们今天讨论的内存是第一块儿,可供我们进行数据存储的内存。

首先0x000 000~0x0007 FFFF并不可以用来进行用户数据存储,这一段固化的代码作用是根据BOOT引脚输入的电平高低来决定将Flash memory、System memory还是SRAM的首地址映射到起始位置。

那么在真正可供我们操作的内存空间中,首先我们来讨论SRAM,SRAM只要芯片没有下电就可以一直存储数据(除非软失效等情形发生)。

Option bytes主要可以设置对 Flash 存储器的读写保护级别,防止未经授权的程序对 Flash 中的代码和数据进行读取或修改,保障程序和数据的安全性。

System memory里面存储着ST原厂编写的bootloader,当我们无法通过工具链下载代码时,可以通过改变boot引脚高低电平的方式选择使用该段内存中的bootloader。我们经常使用的串口升级代码也存储在这一段内存中。

我们平时下载的代码主要就存储在0x0800 0000~0x0807 FFFF中,这512K的内存又可以分为两部分,代码.text段和数据.rodata段。这段内存的第一个字节(0x08000 0000~0x0800 0003)存储着至关重要的MSP指针(栈底指针);第二个字节装着PC指针,PC指针指向了我们的复位函数。

下面介绍SRAM的作用,首先最底部的.data段的数据来源自上图用户代码的.rodatda。那么我们在编程中如何定义变量会导致数据被存储在.data段内部呢?下面介绍了两种特定值可修改的变量定义方式。

int cnt3=1;
fun1(void)
{static int cnt=1;
}

其次.bss段存储两类内容,一类是FreeRTOS中的heap size,另外一类是其他未初始化或者初始化为0的可修改变量;第二类又可以分为3小类,第一类是如同下文中cnt那样的未初始化全局变量,第二类是初始化为0的全局变量,第三类是静态的局部变量。

int cnt;
int cnt1=0;
int fun1(char *argv)
{static int cnt2;}

.s文件中映射单片机堆栈中的数据,msp指针向下压入数据,当msp向下生长影响到队时就会在造成栈溢出。堆中的数据则是用malloc手动分配。

那么在移植freertos的过程中,动态创建的任务与静态创建的任务分别都被存储在了哪里?都在.bss段中的freertos_heap_size中。

下面讨论上下文堆栈:

cortex-M内核拥有双堆栈机制,除了MSP指针外还有一个PSP指针。在 Cortex-M 内核中,PSP(Process Stack Pointer,进程栈指针)是专门用于应用任务(用户任务)的栈指针,与 MSP(Main Stack Pointer,主栈指针)配合实现了内核与用户任务的栈空间分离,是支持实时操作系统(如 FreeRTOS)多任务管理的核心机制之一。

机制原理

  1. 栈指针的分离设计
    Cortex-M 内核有两个栈指针:

    • MSP(主栈指针):默认用于内核模式(如中断服务程序、异常处理、内核代码),复位后默认使用 MSP。
    • PSP(进程栈指针):仅用于用户模式(应用任务),由用户任务代码使用。

    内核通过CONTROL 寄存器的 bit [1] 控制当前使用的栈指针:

    • CONTROL[1] = 0:使用 MSP(内核模式默认)。
    • CONTROL[1] = 1:使用 PSP(用户任务运行时)。
  2. 任务切换时的 PSP 作用
    当发生任务切换(如由调度器触发)时:

    • 内核先将当前任务的寄存器状态(R0-R15 等)压入该任务的 PSP 所指向的栈空间(保存上下文)。
    • 然后加载下一个任务的 PSP 值(从该任务的 TCB 中获取),并从其栈中恢复寄存器状态(恢复上下文)。
    • 最后通过修改 CONTROL 寄存器,使 CPU 切换到 PSP,运行新任务。

核心作用

  1. 实现任务栈隔离
    每个用户任务拥有独立的栈空间(由 PSP 指向),任务间的栈数据互不干扰,避免了多任务运行时的栈冲突,提高了系统稳定性。

  2. 支持实时操作系统的多任务调度
    操作系统(如 FreeRTOS)通过管理每个任务的 PSP 值(存储在 TCB 中),实现快速的任务上下文切换,是多任务并发执行的基础。

  3. 区分内核与用户权限
    MSP 用于内核和异常处理,PSP 用于用户任务,配合内核的特权模式机制,实现了系统资源的权限隔离(如某些寄存器仅能在特权模式下访问)。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenStack 03:创建实例

修改默认安全组 管理规则 添加规则 添加端口22规则 添加ping 规则 下载镜像文件 Get images — Virtual Machine Image Guide documentation https://mirrors.tuna.tsinghua.edu.cn/fedora/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2 …

企业级架构师综合能力项目案例一(各种组件集群搭建+SpringBoot整合)

架构图 用户请求 → Nginx → Spring Cloud Gateway → 微服务集群↓MySQL集群主从复制(ShardingSphere) Redis集群主从复制(Sentinel)ES集群 MongoDB集群(分片)RocketMQ集群 Seata分布式事务搭建集群 Nginx集群和配置┌─────────…

学习stm32 窗口看门狗

窗口看门狗1.WWDG简介窗口看门狗用于监测单片机程序运行时效是否精准,主要检测软件异常,一般用于需要精准检测程序运行时间的场合。不仅防止程序 “卡死不喂狗”,还能避免程序 “异常早喂狗”(如死循环中误执行喂狗指令&#xff0…

Selenium 等待机制:编写稳定可靠的自动化脚本

一、为什么需要等待机制?网页是动态加载的,元素出现的时间不确定。如果脚本在元素还没加载完成时就尝试操作它,就会抛出 NoSuchElementException 异常。三种等待方式:强制等待:time.sleep() - 简单但低效隐式等待&…

蓓韵安禧活性叶酸独立包装防漏贴心设计

蓓韵安禧叶酸新升级 近期,蓓韵安禧在叶酸产品上进行了重要的优化升级。这次升级的核心在于产品形态和使用体验的显著提升,尤其体现在其包装设计上。新版本采用了独立密封的小包装形式,每一份都精准包含每日所需的叶酸量。这种设计不仅有效避免…

8针脚的1.8寸IIC接口的TFT彩屏的八个引脚都需要使用吗?

核心结论 不需要全部使用8个引脚。实际仅需连接 4根核心线(GND, VCC, SCL, SDA) 即可基本工作,其余引脚为功能增强或备用设计。具体需根据屏幕型号确认,但通用规则如下:8针脚功能分解引脚标号典型名称是否必需作用不连…

刷题日记0831

今日计划5道早上起来不困,吃好早饭开始困了,感觉刷不动题,就先做别的事,不困。现在别的事做好了,感觉能刷动题了。开始开始。7/5134. 加油站 中等超时了。看下题解。不是,怎么上数学了?假设从 x…

【2025.8.31】自学Java三个月,谈谈心路历程顺便给自己灌点鸡汤

自学Java三个月,谈谈心得顺便给自己灌点鸡汤 6月1开始上班,到今天刚好三个月。从上班第一天决定开始自学java,到今天也是正好3个月整,想借这个机会简单记录一下学习java的契机和进度,α一些碎碎念。(括号恐…

linux内核trace_begin和trace_end使用分析

1,strace/ftrace的实现和使用 echo 1 > /sys/kernel/debug/tracing/tracing_on echo function > /sys/kernel/debug/tracing/current_tracer 2, 手动插入追踪点 在内核代码中,可以使用trace_printk函数手动插入追踪点,标记代码段的开始和结束: trace_printk(&…

Linux-驱动积累

Linux 设备驱动概述​Linux 设备驱动是内核与硬件交互的核心桥梁,负责屏蔽硬件细节、提供统一操作接口。其以内核模块为主要存在形式,支持动态加载 / 卸载,核心功能涵盖硬件初始化、中断处理、电源管理及数据传输,是嵌入式 Linux …

软考-系统架构设计师 决策支持系统(DSS)详细讲解

个人博客:blogs.wurp.top 一、DSS的核心概念与定位 1. 什么是DSS? DSS是一个交互式的、计算机化的系统,旨在帮助决策者利用数据和模型来解决半结构化(Semi-structured) 或非结构化(Non-structured&#…

《Python 实战:构建一个可扩展的订单管理系统,从基础操作到架构思维》

《Python 实战:构建一个可扩展的订单管理系统,从基础操作到架构思维》 一、引言:用代码管理商业的脉搏 在数字化浪潮席卷各行各业的今天,订单管理系统已成为电商、物流、零售等领域的核心支撑。它不仅承载着交易数据,更是企业运营效率的体现。而 Python,以其简洁优雅的…

【计算机网络】生产问题排查:如何使用Wireshark抓包/读取抓包文件进行网络分析

1 缘起 有一次,公司同事A让同事B看一次请求日志, 同事B说先抓一次包看看请求是否进入服务器-某个服务, 我知道这个事情后,也“参观”了抓包过程, 上面的事件只是一个小插曲,紧接着的第二件事才是写本篇文章的真正动机: 同一天,同事C让同事D配置个服务代理(某种上网方…

网格dp|

lc3665class Solution {public:int uniquePaths(vector<vector<int>>& grid) {const int MOD 1000000007;int m grid.size(), n grid[0].size();vector memo(m, vector(n, array<int, 2>{-1, -1})); // -1 表示没有计算过auto dfs [&](this auto…

烦人的Nano 编辑器,如何退出呢?

对于不熟悉 nano 编辑器的人来说&#xff0c;它的退出方式确实有点反直觉。别担心&#xff0c;这是几乎所有新手都会遇到的困惑。 退出 Nano 编辑器的正确方法 记住这个黄金法则&#xff1a;ctrl键是你的朋友&#xff01; 1. 正常保存并退出&#xff08;最常用&#xff09; 按 …

IDM(Internet Download Managerv 6.38)破除解版下载!IDM 下载器永久免费版!提升下载速度达5倍!安装及使用

软件介绍 IDM&#xff08;Internet Download Manager&#xff09;是一款功能强大的 Windows 平台专业下载加速工具&#xff0c;可加速下载速度、调度任务、续传下载、管理文件。可使下载速度提升至普通浏览器的 5 倍以上&#xff0c;最高可加速 8 倍。IDM 支持 HTTP、FTP、HTTP…

学习Java29天(tcp多发多收)但是无解决客户端启动多个问题

180/189今天看了一些ip的东西WLAN的ip是路由器随机分配的&#xff08;DHCP&#xff09;

Photoshop - Ps Camera Raw 滤镜

使用Adobe Photoshop Camera Raw滤镜对图像进行快速和可逆的编辑。Camera Raw滤镜将图像拖入Photoshop工作区&#xff0c;或者点击菜单栏-文件-打开来打开图像。选中图像的对应的图层&#xff0c;点击菜单栏-滤镜-Camera Raw滤镜&#xff0c;弹出Camera Raw滤镜面板。使用Camer…

Node.js(4)—— http模块基础

下面我们来学nodejs中的http模块。在此之前&#xff0c;你需要有一定的网络知识储备&#xff0c;能知道http&#xff0c;IP&#xff0c;端口是什么并且它们之间的关系。如果还不清楚或比较模糊&#xff0c;可以查看下面的文章&#xff1a; HTTP协议与IP 下面我们开始学习。 目…

后端去拿数据怎么拿?

简单来说&#xff0c;Entity 和 DTO 代表了数据在不同层次和场景下的不同形态和目的。它们最根本的区别在于&#xff1a;职责和目的不同。一句话概括Entity&#xff1a;代表数据库中的表&#xff0c;是业务逻辑的核心&#xff0c;与持久化&#xff08;数据库&#xff09;紧密相…