STM32的内存分配与堆栈

使用过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 用于用户任务,配合内核的特权模式机制,实现了系统资源的权限隔离(如某些寄存器仅能在特权模式下访问)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值