你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32堆栈指针疑问

[复制链接]
STMCU小助手 发布时间:2022-1-29 13:57
1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量。
  1. #include "stm32f10x_lib.h"
  2. #define SP_PROCESS_SIZE             0x200  /* Process stack size */
  3. #define SP_PROCESS                  0x02   /* Process stack */
  4. #define SP_MAIN                     0x00   /* Main stack */
  5. #define THREAD_MODE_PRIVILEGED      0x00   /* Thread mode has privileged access */
  6. #define THREAD_MODE_UNPRIVILEGED    0x01   /* Thread mode has unprivileged access */

  7. ErrorStatus HSEStartUpStatus;
  8. vu8 PSPMemAlloc[SP_PROCESS_SIZE];
  9. vu32 Index = 0, PSPValue = 0, CurrentStack = 0, ThreadMode = 0;

  10. /* Private function prototypes -----------------------------------------------*/
  11. void RCC_Configuration(void);
  12. void NVIC_Configuration(void);


  13. int main(void)
  14. {
  15. #ifdef DEBUG
  16.   debug();
  17. #endif

  18.   //时钟配置
  19.   RCC_Configuration();

  20.   //中断向量表配置
  21.   NVIC_Configuration();

  22.   //STM32有一个主堆栈指针MSP,和线程堆栈指针PSP,把进程堆栈指针指向这个数组的高地址,因为堆栈指针是向下增长的
  23. /* Switch Thread mode Stack from Main to Process -----------------------------*/
  24.   /* Initialize memory reserved for Process Stack */
  25.   for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
  26.   {
  27.     PSPMemAlloc[Index] = 0x00;
  28.   }
  29.   //系统上电,是在线程模式,特权级别下,所以可以修改CONTROL寄存器,这个寄存器选择特权级和用户级,还有系统选哪个堆栈指针
  30.   /* Set Process stack value */
  31.   __MSR_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE);
  32.   //选择线程堆栈作为线程模式的堆栈,有点绕口
  33.   /* Select Process Stack as Thread mode Stack */
  34.   __MSR_CONTROL(SP_PROCESS);

  35.   /* Get the Thread mode stack used */
  36.   if((__MRS_CONTROL() & 0x02) == SP_MAIN)
  37.   {
  38.     /* Main stack is used as the current stack */
  39.     CurrentStack = SP_MAIN;
  40.   }
  41.   else
  42.   {
  43.     /* Process stack is used as the current stack */
  44.     CurrentStack = SP_PROCESS;

  45.     /* Get process stack pointer value */
  46.     PSPValue = __MRS_PSP();
  47.   }

  48. /* Switch Thread mode from privileged to unprivileged ------------------------*//切换线程模式到非特权
  49.   /* Thread mode has unprivileged access */
  50.   __MSR_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);
  51.   /* Unprivileged access mainly affect ability to:
  52.       - Use or not use certain instructions such as MSR fields
  53.       - Access System Control Space (SCS) registers such as NVIC and SysTick */

  54.   /* Check Thread mode privilege status */ //检查当前是特权还是用户级别
  55.   if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  56.   {
  57.     /* Thread mode has privileged access  */
  58.     ThreadMode = THREAD_MODE_PRIVILEGED;
  59.   }
  60.   else
  61.   {
  62.     /* Thread mode has unprivileged access*/
  63.     ThreadMode = THREAD_MODE_UNPRIVILEGED; //应该是用户级别
  64.   }

  65. /* Switch back Thread mode from unprivileged to privileged -------------------*/  //切换到特权模式
  66.   /* Try to switch back Thread mode to privileged (Not possible, this can be
  67.      done only in Handler mode) */
  68.   __MSR_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);

  69.   /* Generate a system call exception, and in the ISR switch back Thread mode
  70.     to privileged */
  71.   __SVC(); //产生中断,进入handler模式,特权级别

  72.   /* Check Thread mode privilege status */
  73.   if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  74.   {
  75.     /* Thread mode has privileged access  */
  76.     ThreadMode = THREAD_MODE_PRIVILEGED;  //应该是特权级别
  77.   }
  78.   else
  79.   {
  80.     /* Thread mode has unprivileged access*/
  81.     ThreadMode = THREAD_MODE_UNPRIVILEGED;
  82.   }

  83.   while (1)
  84.   {
  85.   }
  86. }
复制代码

2. 暂时不明白这个程序什么用途,只是学习的过程中遇到了,拿出来研究一下。
Cortex-M3处理器支持两种处理器的操作模式,还支持两级特权操作。
两种操作模式分别为:处理者模式(handler mode)和线程模式(thread mode)。引入两个模式的本意,是用于区别普通应用程序的代码和异常服务例程的代码——包括中断服务例程的代码。Cortex-M3的另一个侧面则是特权的分级——特权级和用户级。这可以提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。处理器支持两种特权级,这也是一个基本的安全模型。
3. 在CM3运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级;但是异常服务例程必须在特权级下执行。复位后,处理器默认进入线程模式,特权极访问。在特权级下,程序可以访问所有范围的存储器(如果有MPU,还要在MPU规定的禁地之外),并且可以执行所有指令。
在特权级下的程序可以为所欲为,但也可能会把自己给玩进去——切换到用户级。一旦进入用户级,再想回来就得走“法律程序”了——用户级的程序不能简简单单地试图改写CONTROL寄存器就回到特权级,它必须先“申诉”:执行一条系统调用指令(SVC)。这会触发SVC异常,然后由异常服务例程(通常是操作系统的一部分)接管,如果批准了进入,则异常服务例程修改CONTROL寄存器,才能在用户级的线程模式下重新进入特权级。事实上,从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处理器总是先切换入特权级,并且在异常服务例程执行完毕退出时
4.如果根据下表和上面解释重新看代码的话,应该很清楚了。

1300009-20171222170030818-1131604041.jpg

5. 在看下CONTROL寄存器介绍

1300009-20171222170243725-510842683.jpg

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

收藏 评论0 发布时间:2022-1-29 13:57

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版