stm32的core-皇冠最新app版本

×
嵌入式 > 嵌入式开发 > 详情

stm32的core_cm3.c文件

发布时间:2026-06-22 发布时间:
|
上一章提到了对于stm32的堆栈的研究。实际上在查询资料时,看到有大神提到可以获取栈的指针。因为一般要验证都是存在栈溢出的问题,把他贴出来供大家研究。(我没有实际验证)
  • voidhardfault_handler(void)
  • {
  • uint32_tr_sp;
  • r_sp=__get_psp();//获取sp的值
  • perror(error,memoryaccesserror!);
  • panic(r_sp);
  • while(1);
  • }
  • 获取u200b进程堆栈指针并打印出来!__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寄存器。



『本文转载自网络,皇冠最新app版本的版权归原作者所有,如有侵权请联系删除』

网站地图