stm32的Core_cm3.c文件

本文介绍如何在STM32上通过__get_PSP()函数获取进程堆栈指针(PSP),并提供了Core_cm3.c文件中与堆栈操作相关的函数解析,包括设置和获取主堆栈指针(MSP)等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博文参考了其它博客或资料,均已在最后列出。

       上一章提到了对于stm32的堆栈的研究。实际上在查询资料时,看到有大神提到可以获取栈的指针因为一般要验证都是存在栈溢出的问题,把他贴出来供大家研究。(我没有实际验证)

  • void HardFault_Handler(void)  
  • {  
  •   uint32_t r_sp ;  
  •   r_sp = __get_PSP(); //获取SP的值  
  •   PERROR(ERROR,Memory Access Error!);  
  •   Panic(r_sp);  
  •    
  •   while (1);  
  • }  

  • 获取​进程堆栈指针并打印出来!__get_PSP()函数为Core_Core_cm3.c中的函数。他这个函数解析一下供大家查看:
  • Core_cm3.c里面的东西

首先是汇编关键字__ASM和__INLINE的宏定义,支持不同的编译器。由于使用的是Keil,所以就只看第一种,__CC_ARM

1. __ASMuint32_t __get_PSP(void):获取进程堆栈指针PSP。

2. __ASMvoid __set_PSP(uint32_t topOfProcStack):设置PSP。

3. __ASM uint32_t __get_MSP(void):获取主堆栈指针MSP。

4. __ASMvoid __set_MSP(uint32_t mainStackPointer):设置MSP。

5. __ASMuint32_t __REV16(uint16_t value):反转半字中字节顺序,如0xABCD反转后得到0xCDAB。

6. __ASMint32_t __REVSH(int16_t value):反转字节顺序,并做符号拓展。就是在__REV16函数得到的结果上再进行一次符号拓展。这两个函数主要是方便进行大小端的切换。

7. __ASMvoid __CLREX(void):清除由LDREX指令造成的互斥锁。LDREX和STREX是Cortex用来实现互斥访问,保护临界资源的指令,LDREX执行后,只有离它最近的一条存储指令(STR,STREX)才能执行,其他的存储指令都会被驳回,而CLREX就是用于清除互斥访问状态的标记。

8. __ASMuint32_t  __get_BASEPRI(void):获取BASEPRI寄存器的值,优先级号高于该寄存器的中断都会被屏蔽(优先级号越大,优先级越低),为零时不屏蔽任何中断。

9. __ASMvoid __set_BASEPRI(uint32_t basePri):设置BASEPRI的值。

10.__ASM uint32_t __get_PRIMASK(void):PRIMASK是一个只有一位的寄存器,置位时屏蔽绝大部分的异常中断,只剩下NMI和HardFault可以响应。

11.__ASM void __set_PRIMASK(uint32_t priMask):设置PRIMASK的值。

12.__ASM uint32_t  __get_FAULTMASK(void):FAULTMASK也是一个只有一位的寄存器,为1时只有NMI才能响应,其他异常与中断全部被屏蔽。

13.__ASM void __set_FAULTMASK(uint32_t faultMask):设置FAULTMASK的值。

14.__ASM uint32_t __get_CONTROL(void):获取CONTROL的值。寄存器CONTROL只有两位。CONTROL[0]选择特权级别,0为特权级,1为敌用户级。CONTROL[1]用于选择堆栈指针,0为MSP,1为PSP。

15.__ASM void __set_CONTROL(uint32_t control):设置CONTROL寄存器的值。

BASEPRI,PRIMASK,FAULTMASK,CONTROL都只能在特权模式下被修改。

 

还有两个文件,一个是Core_cmFunc.h和 Core_cmInstr.h  这两个文件时干嘛的,第一个文件是不同编译器下的一些系统级的汇编函数,第二个文件是不同编译器下的指令,我猜Keil公司这样做是为了兼容不同的编译器做设计的。

 

最后剩下Core_cm3.h文件了,这个文件时内核文件,就是定义了一些Cortex-M3的寄存器和一些函数,包括NVIC,MPU,SCB,SysTick,Debug寄存器。


参考:

1、http://blog.csdn.net/sunjiajiang/article/details/7582752​

2、http://blog.csdn.net/denghuanhuandeng/article/details/8167119

### STM32 编译错误缺少 `core_cm3.o` 文件解决方案 当遇到 STM32 使用 MDK 工具链编译时提示缺少 `core_cm3.o` 文件的情况,通常是因为编译器设置或项目配置存在问题。以下是详细的分析与解决方法: #### 1. **确认编译器版本** 如果使用的 MDK 版本较新(如 MDK5 或更高),可能会存在编译器选项不匹配的问题。最新版的 MDK 默认使用 ARM Compiler 6 (AC6),而旧版本的启动文件可能基于 ARM Compiler 5 (AC5)[^4]。 - 如果项目的启动文件或其他 CMSIS 配置依赖 AC5,则需要手动切换到 AC5 模式。 - 打开 MDK 的工程设置界面,在 `"Target Options"` 中找到 `"ARM Compiler Version"` 设置项,将其更改为 `"Use default compiler version 5"`。 #### 2. **检查核心支持库** CMSIS 库中的 `core_cm3.c` 是 Cortex-M3 处理器的核心实现部分。如果没有正确链接该文件或将其实现排除在外,可能导致无法生成对应的 `.o` 文件[^3]。 - 确认项目中是否包含了完整的 CMSIS 核心源码路径。具体来说,需确保以下路径已添加至 Include 和 Source 路径中: - `<CMSIS_Include_Path>/Core/Source` - `<CMSIS_Include_Path>/Device/ST/STM32Fxxx/Source/Templates/gcc` ```c // 示例:确保 core_cm3.c 正确加入工程 #include "core_cm3.h" ``` #### 3. **验证目标设备定义** 某些情况下,未正确定义目标 MCU 型号也可能引发此问题。MCU 定义决定了哪些外设驱动程序以及核心文件会被加载。 - 在预处理宏 (`Preprocessor Macros`) 中检查是否存在类似如下定义: ```plaintext USE_HAL_DRIVER STM32F103RCT6 ``` 这些宏会引导编译器选择适合当前硬件平台的具体实现[^2]。 #### 4. **重新生成对象文件** 尝试清理整个工程项目并强制重新构建所有模块。这可以避免因缓存残留而导致的部分中间产物丢失现象。 - 清除现有输出目录下的所有临时文件; - 利用菜单命令执行 Full Rebuild 动作。 --- ### 总结代码片段示例 下面是一个简单的测试脚本用于验证基本环境搭建无误与否: ```c /* main.c */ #include "stm32f1xx_hal.h" int main(void){ HAL_Init(); // 初始化HAL库 while(1); } ``` 上述代码应能正常通过编译流程而不报告任何缺失错误消息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值