STM32在bootloader跳转到application时设置MSP

news/2024/12/26 3:50:52/

1. 简介

在做bootloader 跳转到application时,经常会看到设置MSP的操作__set_MSP(*(__IO uint32_t*) APPLICATION_ENTRY);

1.1 MSP的作用

在STM32微控制器中,MSP(Main Stack Pointer,主堆栈指针)是一个非常重要的寄存器,它用于管理堆栈。堆栈是用于临时存储数据和保持子程序返回地址的区域。MSP在以下几种情况下发挥关键作用:

  1. 启动时初始化:在系统启动时,MSP会被初始化为向量表中的初始值。这个初始值通常在启动文件(如startup_stm32fxx.s)中定义。

  2. 异常和中断处理:当发生异常或中断时,MSP用于保存当前的程序状态,包括寄存器内容。这样,当异常或中断处理完成后,可以恢复原来的程序状态并继续执行。

  3. 操作系统使用:在使用实时操作系统(RTOS)时,MSP通常用于处理系统级的中断和异常,而每个任务可能有自己的堆栈指针(PSP,Process Stack Pointer)。MSP和PSP的切换由操作系统来管理,以实现任务之间的切换。

  4. 函数调用:在函数调用过程中,MSP用于保存局部变量、函数参数和返回地址。当函数调用结束时,MSP会恢复到调用前的状态。

MSP的值可以通过特定的汇编指令(如MRSMSR)来读取和修改。在C语言编程中,通常不需要直接操作MSP,但在底层驱动开发或调试时,了解MSP的作用和如何操作它是很有帮助的。

下面是一个简单的汇编代码示例,展示如何读取和写入MSP:

MRS R0, MSP  ; 读取MSP的值到R0寄存器
MSR MSP, R0  ; 将R0寄存器的值写入MSP

通过这些操作,可以查看和修改MSP的值,以便进行调试或特定的系统级操作。

1.2 MSP的设置

MSP 通常在特权模式下使用, 由硬件自动管理和切换, 在系统启动时初始化。

  • 系统初始化时,会执行Reset_Handler, 先看下这个函数
Reset_Handler:ldr   r0, =_estackmov   sp, r0          /* set stack pointer *//* Call the clock system initialization function.*/bl  SystemInit/* Copy the data segment initializers from flash to SRAM */ldr r0, =_sdataldr r1, =_edataldr r2, =_sidatamovs r3, #0b LoopCopyDataInit......

从上述代码的可以看出, Reset_Handler_estack加载到SP(堆栈指针), 而_estack在链接文件中定义
/* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

以STM32G070为例, 在.map文件中可以看到_estack的值

0x20009000                        _estack = (ORIGIN (RAM) + LENGTH (RAM))
0x00000200                        _Min_Heap_Size = 0x200
0x00000400                        _Min_Stack_Size = 0x400

所以上电初始化时, MSP的值应该是 0x20009000.

2. 跳转时是否必须显示的设置MSP的值

2.1 _estack的值存储在哪里

上述1.2节,介绍了_estack的初始化值为0x20009000,但这个值存储在哪个地址?答案是在中断向量表中:

 .section .isr_vector,"a",%progbits.type g_pfnVectors, %objectg_pfnVectors:.word _estack.word Reset_Handler.word NMI_Handler.word HardFault_Handler.word 0.word 0.word 0.word 0.word 0.word 0.word 0.word SVC_Handler.word 0.word 0.word PendSV_Handler.word SysTick_Handler.word WWDG_IRQHandler                   /* Window WatchDog              */.word 0                                /* reserved                     */......

由中断向量表代码段可看出, _estack在向量表的首地址; 查看.map文件:

.isr_vector     0x08000000       0xb80x08000000                        . = ALIGN (0x4)*(.isr_vector).isr_vector    0x08000000       0xb8 ./Core/Startup/startup_stm32g070cbtx.o0x08000000                g_pfnVectors0x080000b8                        . = ALIGN (0x4)

向量表的首地址为isr_vector 0x08000000;所以_estack的值存储在 0x08000000, 值为 0x20009000.
通过JLINK可以读出FLASH里的值
在这里插入图片描述

或者查看hex文件,同样可以找到
在这里插入图片描述

2.2 跳转时设置 MSP

跳转时设置MSP的值:

__set_MSP(*(__IO uint32_t*) APPLICATION_ENTRY);

其中APPLICATION_ENTRY就是application的起始地址, 这里假设APPLICATION_ENTRY = 0x0800a200, 那这个地址理论上存放的也是application的 _estack, 通过JLINK读取这个地址的值验证:
在这里插入图片描述

所以,__set_MSP(*(__IO uint32_t*) APPLICATION_ENTRY);这句话的意思也就是把application的_estack赋值给MSP。

2.3 跳转时不显式的设置MSP

如果跳转时不加__set_MSP(*(__IO uint32_t*) APPLICATION_ENTRY);, 会不会有问题?
先看跳转的代码:

// Start applicationdw_reset = *(uint32_t *)(APPLICATION_START);pf_reset = (t_VOID_FUNC)( dw_reset );pf_reset();

这里APPLICATION_START = 0x0800A204,也就是bootloader 直接跳转到application的 Reset_Handler。至此,又回到了1.2节, 在Reset_Handler里会自动将 _estack的值赋给SP。
所以,如果Reset_Handler里设置了SP的值,则跳转时,不是必须要显式的设置MSP的值。


http://www.ppmy.cn/news/1558161.html

相关文章

《第十二部分》1.STM32之RTC实时时钟介绍---BKP实验

本章将介绍一种计数计时的外设 RTC实时时钟-----Whappy STM32提供了4中时钟来源! 函数名功能作用void BKP_DeInit(void);复位备份区域寄存器配置,将备份域的所有寄存器恢复到默认状态。void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel);配置…

遥感影像目标检测:从CNN(Faster-RCNN)到Transformer(DETR

我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB,遥感大数据时…

如何使用vscode解决git冲突

在使用VSCode时,遇到Git冲突是很常见的情况。Git冲突是指当多个人同时修改同一个文件的同一行或相邻行时,Git无法自动决定应该保留哪一个修改,需要手动解决这个冲突。 要解决Git冲突,可以按照以下步骤操作: 1. 打开V…

概率论 期末 笔记

第一章 随机事件及其概率 利用“四大公式”求事件概率 全概率公式与贝叶斯公式 伯努利概型求概率 习题 推导 一维随机变量及其分布 离散型随机变量(R.V)求分布律 利用常见离散型分布求概率 连续型R.V相关计算 利用常见连续型分布的计算 均匀分布 正态…

centos server系统新装后的网络配置

当前状态: ping www.baidu.com报错 1、检查IP ip addr show记录要编辑的网卡 link/ether 后的XX:XX:XX:XX:XX:XX号 2、以em1为例: vi /etc/sysconfig/network-scripts/ifcfg-em1,新增如下行: HWADDRXX:XX:XX:XX:XX:XX(具体值…

【kubernetes】资源管理方式

目录 1. 说明2. 命令式对象管理3. 命令式对象配置4. 声明式对象配置5. 三种方式的对比 1. 说明 1.在Kubernetes(k8s)中,资源管理是一个核心功能,它允许用户通过操作资源来管理Kubernetes集群。2.Kubernetes将所有的内容都抽象为资…

TipTap编辑器:现代化的富文本编辑解决方案

简介 TipTap是一个基于 ProseMirror 的现代化富文本编辑器框架。它具有模块化、可扩展和响应式的特点,特别适合用于Vue、React等现代前端框架中。 主要特点 1. 模块化设计 import { Editor } from tiptap/core import StarterKit from tiptap/starter-kitconst …

STM32第十一课:STM32-基于标准库的42步进电机的简单IO控制(附电机教程,看到即赚到)

一:步进电机简介 步进电机又称为脉冲电机,简而言之,就是一步一步前进的电机。基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩,步进电机的角位移量与输入的脉冲个数严格成正…