1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量。

 #include "stm32f10x_lib.h"
#define SP_PROCESS_SIZE 0x200 /* Process stack size */
#define SP_PROCESS 0x02 /* Process stack */
#define SP_MAIN 0x00 /* Main stack */
#define THREAD_MODE_PRIVILEGED 0x00 /* Thread mode has privileged access */
#define THREAD_MODE_UNPRIVILEGED 0x01 /* Thread mode has unprivileged access */ ErrorStatus HSEStartUpStatus;
vu8 PSPMemAlloc[SP_PROCESS_SIZE];
vu32 Index = , PSPValue = , CurrentStack = , ThreadMode = ; /* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void NVIC_Configuration(void); int main(void)
{
#ifdef DEBUG
debug();
#endif //时钟配置
RCC_Configuration(); //中断向量表配置
NVIC_Configuration(); //STM32有一个主堆栈指针MSP,和线程堆栈指针PSP,把进程堆栈指针指向这个数组的高地址,因为堆栈指针是向下增长的
/* Switch Thread mode Stack from Main to Process -----------------------------*/
/* Initialize memory reserved for Process Stack */
for(Index = ; Index < SP_PROCESS_SIZE; Index++)
{
PSPMemAlloc[Index] = 0x00;
}
//系统上电,是在线程模式,特权级别下,所以可以修改CONTROL寄存器,这个寄存器选择特权级和用户级,还有系统选哪个堆栈指针
/* Set Process stack value */
__MSR_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE);
//选择线程堆栈作为线程模式的堆栈,有点绕口
/* Select Process Stack as Thread mode Stack */
__MSR_CONTROL(SP_PROCESS); /* Get the Thread mode stack used */
if((__MRS_CONTROL() & 0x02) == SP_MAIN)
{
/* Main stack is used as the current stack */
CurrentStack = SP_MAIN;
}
else
{
/* Process stack is used as the current stack */
CurrentStack = SP_PROCESS; /* Get process stack pointer value */
PSPValue = __MRS_PSP();
} /* Switch Thread mode from privileged to unprivileged ------------------------*//切换线程模式到非特权
/* Thread mode has unprivileged access */
__MSR_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);
/* Unprivileged access mainly affect ability to:
- Use or not use certain instructions such as MSR fields
- Access System Control Space (SCS) registers such as NVIC and SysTick */ /* Check Thread mode privilege status */ //检查当前是特权还是用户级别
if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
{
/* Thread mode has privileged access */
ThreadMode = THREAD_MODE_PRIVILEGED;
}
else
{
/* Thread mode has unprivileged access*/
ThreadMode = THREAD_MODE_UNPRIVILEGED; //应该是用户级别
} /* Switch back Thread mode from unprivileged to privileged -------------------*/ //切换到特权模式
/* Try to switch back Thread mode to privileged (Not possible, this can be
done only in Handler mode) */
__MSR_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS); /* Generate a system call exception, and in the ISR switch back Thread mode
to privileged */
__SVC(); //产生中断,进入handler模式,特权级别 /* Check Thread mode privilege status */
if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
{
/* Thread mode has privileged access */
ThreadMode = THREAD_MODE_PRIVILEGED; //应该是特权级别
}
else
{
/* Thread mode has unprivileged access*/
ThreadMode = THREAD_MODE_UNPRIVILEGED;
} while ()
{
}
}

2. 暂时不明白这个程序什么用途,只是学习的过程中遇到了,拿出来研究一下。

Cortex-M3处理器支持两种处理器的操作模式,还支持两级特权操作。
两种操作模式分别为:处理者模式(handler mode)和线程模式(thread mode)。引入两个模式的本意,是用于区别普通应用程序的代码和异常服务例程的代码——包括中断服务例程的代码。Cortex-M3的另一个侧面则是特权的分级——特权级和用户级。这可以提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。处理器支持两种特权级,这也是一个基本的安全模型。

3. 在CM3运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级;但是异常服务例程必须在特权级下执行。复位后,处理器默认进入线程模式,特权极访问。在特权级下,程序可以访问所有范围的存储器(如果有MPU,还要在MPU规定的禁地之外),并且可以执行所有指令。

在特权级下的程序可以为所欲为,但也可能会把自己给玩进去——切换到用户级。一旦进入用户级,再想回来就得走“法律程序”了——用户级的程序不能简简单单地试图改写CONTROL寄存器就回到特权级,它必须先“申诉”:执行一条系统调用指令(SVC)。这会触发SVC异常,然后由异常服务例程(通常是操作系统的一部分)接管,如果批准了进入,则异常服务例程修改CONTROL寄存器,才能在用户级的线程模式下重新进入特权级。事实上,从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处理器总是先切换入特权级,并且在异常服务例程执行完毕退出时

4.如果根据下表和上面解释重新看代码的话,应该很清楚了。

5. 在看下CONTROL寄存器介绍

6. 如此一来,基本搞明白了。

STM32堆栈指针疑问的更多相关文章

  1. 51单片机的堆栈指针(SP)

    堆栈指针(SP,Stack Pointer),专门用于指出堆栈顶部数据的地址. 那么51单片机的堆栈在什么地方呢?由于单片机中存放数据的区域有限,我们不能够专门分配一块地方做堆栈,所以就在内存(RAM ...

  2. Keil C51里关于堆栈指针的处理

    Keil C是非常优秀的C51编译器,可能是最好的C51编译器,提供各种优化模式,对变量的优化和地址安排做得非常好.这是用C语言写代码的好处之一,如果用汇编写,得费一大番功夫给各个变量安排内存物理地址 ...

  3. (转)UCOSII在任务切换与出入中断时堆栈指针的使用

    1 uc/os ii在M3中的堆栈结构 1.1 M3入账序列  1.2 加上手工入栈序列  2 PendSV在Cortex-M3中的应用 Systick为嵌入到内核中,优先级比一般中断优先级高.若在一 ...

  4. 程序计数器(PC)、堆栈指针(SP)与函数调用过程

    PC(program counter)是CPU中用于存放下一条指令地址的寄存器,SP为堆栈指针.下面将介绍函数调用过程中CPU对PC和SP这两个寄存器的操作. 假设有如下函数Fun Fun() { … ...

  5. Cortex-M3 双堆栈指针(MSP&PSP)

    [双堆栈指针(MSP&PSP)] Cortex-M3内核中有两个堆栈指针(MSP & PSP),但任何时刻只能使用到其中一个. 复位后处于线程模式特权级,默认使用MSP. 通过SP访问 ...

  6. STM32堆栈溢出

    在使用STM32读取SD Card的文件时,总是会卡死在读函数那里 res = f_read(&fsrc, gbuffer, sizeof(gbuffer)-1, &br); 而且出现 ...

  7. 【转】 BSS段 数据段 代码段 堆栈 指针 vs 引用

    原文:http://blog.csdn.net/godspirits/article/details/2953721 BSS段 数据段 代码段 堆栈 (转+) 声明:大部分来自于维基百科,自由的百科全 ...

  8. 堆栈指针 ---delete 使用

    对拥有堆中一个有效对象的地址的指针进行删除操作的结果,是将这个堆内存的状态从“使用中” 变为“可用”(此时的可用就是指可以调用内存)释放了,可以再次覆盖此处;;     对指针内存进行删除操作后,指针 ...

  9. STM32 堆栈使用解析

    安富莱_STM32-V5开发板_μCOS-III教程.pdf 第4章

随机推荐

  1. Cocos2d-x 3.1.1 学习日志3--C++ 初始化类的常量数据成员、静态数据成员、常量静态数据成员

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u011292087/article/details/37598919 有关const成员.stati ...

  2. PHP---------Smarty模板

    Smarty模板 是做什么用的?? 是将前端的显示和后台的逻辑进行分离,就相当于把前台显示的页面和后台要实现的某些功能的逻辑给分离出来了,分离在两个文件里,也就是说,前端只负责显示,后端只负责逻辑操作 ...

  3. 生成并部署SSH key

    1.如何生成ssh公钥 你可以按如下命令来生成 sshkey: ssh-keygen -t rsa -C "xxxxx@xxxxx.com" # Generating public ...

  4. Linux关于压缩和解压缩实例

    在谈到压缩和解压缩,我想说说它们的应用场景,其实它们主要的应用场景是有这么几个方面? (1)备份(几十个数据库每天进行备份,即包含数据又包含脚本,还有其他十分重要的日志文件等等); (2)降低服务器存 ...

  5. CentOS 7安装简介及基本操作

    计算机基本概念: 1.计算机硬件组成: 2.计算机系统结构: 3.操作系统的功能:硬件驱动.进程管理.内存管理.网络管理.安全管理.文件管理等. 4.OS通用目的的软件程序:用户<-->应 ...

  6. HTML CSS STYLE USER Font Awesome Definition Content Attribute

    在css样式表中写样式: 其中content使用图标类对应的字符编码如下

  7. ARM 汇编指令集 特点之一:指令后缀

    1.同一 指令 添加不同的后缀 就会有不同的功能! 例子: B (Byte)  功能不变,操作长度变为8位 H (Half Word) 功能不变,操作长度变为16位 S(Signed) 功能不变,操作 ...

  8. GoldenGate -- OGG EXTRACT进程 OGG-00446 报错

    -- :: INFO OGG- Positioning to (Thread ) Sequence , RBA , SCN 0.470706262. Source Context : SourceMo ...

  9. 02 看懂Oracle执行计划

    看懂Oracle执行计划   最近一直在跟Oracle打交道,从最初的一脸懵逼到现在的略有所知,也来总结一下自己最近所学,不定时更新ing… 一:什么是Oracle执行计划? 执行计划是一条查询语句在 ...

  10. mysql主从延迟复制

    需求描述 正常情况下我们是不会有刻意延迟从库的需求的,因为正常的线上业务自然是延迟越低越好.但是针对测试场景,业务上偶尔需要测试延迟场景下业务是否能正常运行. 解决方案 针对这种场景mysql有一个叫 ...