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

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

[复制链接]
STMCU小助手 发布时间:2022-1-29 13:57
1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量。
  1. #include "stm32f10x_lib.h"( D4 |! W+ M) h* ~" w# _# L4 l
  2. #define SP_PROCESS_SIZE             0x200  /* Process stack size */3 j9 P7 Q8 Q( b* s# ^
  3. #define SP_PROCESS                  0x02   /* Process stack */
    + t6 D7 R8 ]' A
  4. #define SP_MAIN                     0x00   /* Main stack */
    5 P7 Y7 R& u% `0 X- i) e" s" O
  5. #define THREAD_MODE_PRIVILEGED      0x00   /* Thread mode has privileged access */
    7 }) L$ F- j2 l" V+ U
  6. #define THREAD_MODE_UNPRIVILEGED    0x01   /* Thread mode has unprivileged access */
    : L. v" n0 C% z6 B' r( v* e- }
  7. 7 b% \) ?- z6 m" Y9 w
  8. ErrorStatus HSEStartUpStatus;' ?* J. N$ L& i" O8 z7 [1 o
  9. vu8 PSPMemAlloc[SP_PROCESS_SIZE];
    # e/ E9 `* M9 T. A5 s
  10. vu32 Index = 0, PSPValue = 0, CurrentStack = 0, ThreadMode = 0;* j8 K2 \+ e8 f) P9 f9 U
  11. ; I' c& h6 S# u: N0 @! N5 x
  12. /* Private function prototypes -----------------------------------------------*/
    3 `$ N2 T2 c' Q+ ?3 Z
  13. void RCC_Configuration(void);. x' P& \$ H* S# a  y9 P9 P
  14. void NVIC_Configuration(void);8 n+ V' a5 J& B& q& u
  15. 3 f3 n* \' W6 j( N+ F

  16. ) _) D* x. z5 s0 e* i
  17. int main(void)5 J6 z# M& ^3 N5 s; X' K4 T
  18. {
      g) w4 n! k$ k4 t- ^, H. }
  19. #ifdef DEBUG" a; D. C- c0 d% ~
  20.   debug();
    " s2 m+ r: }$ D  E: i
  21. #endif2 @+ K) H* G* z* u& P6 b/ N

  22. / W8 a& K# q4 _  X+ s1 ~! w  x
  23.   //时钟配置
    " b" o; H0 J, x; {7 a/ w
  24.   RCC_Configuration();
    ! J) T( \- D+ n4 X: ?2 O; c
  25. 7 @& B3 F8 P" s$ `2 h/ G
  26.   //中断向量表配置) P7 E" l  u( q+ w
  27.   NVIC_Configuration();
    " q0 d& h& B4 h! r

  28. $ K9 v7 D- C7 }& S
  29.   //STM32有一个主堆栈指针MSP,和线程堆栈指针PSP,把进程堆栈指针指向这个数组的高地址,因为堆栈指针是向下增长的, y1 Q' x$ H; L. K& L. J
  30. /* Switch Thread mode Stack from Main to Process -----------------------------*/
    8 t) E7 T# c+ Q1 I- H
  31.   /* Initialize memory reserved for Process Stack */* ]/ @: G( p! K( `- g
  32.   for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
    6 t" B( N) p& t) L4 q
  33.   {
    ) R& a# T, j! C! u/ D
  34.     PSPMemAlloc[Index] = 0x00;
    # H, c% h  `+ ~/ C8 Q6 n
  35.   }
    ; q; s; z- `, M. m" k
  36.   //系统上电,是在线程模式,特权级别下,所以可以修改CONTROL寄存器,这个寄存器选择特权级和用户级,还有系统选哪个堆栈指针0 ?2 ^" H0 [, n" B1 m( m" F2 I, r9 J
  37.   /* Set Process stack value */
    & V( m3 A' p. ?( @( c
  38.   __MSR_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE);
    ) e( g! ?7 P4 [- C+ ?
  39.   //选择线程堆栈作为线程模式的堆栈,有点绕口
    % @# b! F8 j7 {+ s' }% E
  40.   /* Select Process Stack as Thread mode Stack */
      f! Z6 ], i1 N1 \# f
  41.   __MSR_CONTROL(SP_PROCESS);
    . D  H' k: S; ~7 T0 H
  42. 0 B  U0 ^, B4 M. g" A; W
  43.   /* Get the Thread mode stack used */' k. a: M5 x8 E4 H' \& _
  44.   if((__MRS_CONTROL() & 0x02) == SP_MAIN)
    6 n/ |0 a  D8 b( s. t* K5 w
  45.   {: ?9 A  H( G$ p9 d: I
  46.     /* Main stack is used as the current stack */6 q' |. Z' C) H3 |1 z* f
  47.     CurrentStack = SP_MAIN;
    * D: P. {+ r4 x& o2 D
  48.   }/ k$ \! b6 I; H+ v1 ~7 y, X  r& G
  49.   else* ]* B4 h/ X3 I0 x; o4 z
  50.   {- O  c) s/ S4 A/ U
  51.     /* Process stack is used as the current stack */
    * M# Q. }8 T; D/ M3 @
  52.     CurrentStack = SP_PROCESS;9 k8 M% r6 W5 U
  53. % }7 `7 D4 Y# t6 b0 V3 B
  54.     /* Get process stack pointer value */
    + A" M2 Q. @- @7 T! }' n5 s
  55.     PSPValue = __MRS_PSP();
    * B5 D) G8 L/ z* e
  56.   }, p; u4 m4 u9 g. M, e
  57. ' L. w7 ^$ Z3 y$ B, n* r1 m0 a: A
  58. /* Switch Thread mode from privileged to unprivileged ------------------------*//切换线程模式到非特权' y  V  G) S9 v0 z9 m# W, E. L0 v
  59.   /* Thread mode has unprivileged access */* c; N8 u& @+ Z, \
  60.   __MSR_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);" @/ Z5 y3 ^3 }3 L! E2 V2 r
  61.   /* Unprivileged access mainly affect ability to:
    ( \6 R: R0 ~3 y! Z: _( L  J. M! g
  62.       - Use or not use certain instructions such as MSR fields' p, Q+ h1 d# o
  63.       - Access System Control Space (SCS) registers such as NVIC and SysTick */8 ?* d# ~/ ]% Z2 P+ @7 z

  64. . M- }; ?4 k% s( u0 c
  65.   /* Check Thread mode privilege status */ //检查当前是特权还是用户级别' d! O6 B# K0 J, U
  66.   if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)7 `+ V- A% _/ F3 H  [/ g2 C
  67.   {
    ; q1 e0 M( G9 P
  68.     /* Thread mode has privileged access  */- S: {  f/ B' t  B
  69.     ThreadMode = THREAD_MODE_PRIVILEGED;
    5 z! g, l9 H% O- l* W
  70.   }
    2 Y5 `. l# H# ~/ g+ e2 V' [  B& _
  71.   else
    4 h2 V+ Z, h$ ?: _
  72.   {
    + z/ Z8 u! S  ?1 G; P
  73.     /* Thread mode has unprivileged access*/4 H0 @4 y2 x  t* l8 l8 j) x
  74.     ThreadMode = THREAD_MODE_UNPRIVILEGED; //应该是用户级别
    : F! F9 F* l* G
  75.   }7 c& r) c4 _  Y. r$ k( M
  76. 5 c! U3 ]2 y& H
  77. /* Switch back Thread mode from unprivileged to privileged -------------------*/  //切换到特权模式
    : I% \" j4 g8 S9 Q5 ~
  78.   /* Try to switch back Thread mode to privileged (Not possible, this can be
    ' T8 J; B; g4 i# c1 q4 `
  79.      done only in Handler mode) */
    9 m( d! t# L7 e, k; l) S2 `
  80.   __MSR_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);
    5 H: y" m& S8 i  T* a, u' L# p3 d

  81. & l9 C3 V; _1 h, c" S9 g
  82.   /* Generate a system call exception, and in the ISR switch back Thread mode* \$ d  U$ k$ C/ b8 j( f, q& |
  83.     to privileged */
    + l* w' K/ l! c" _# O$ T+ D* n
  84.   __SVC(); //产生中断,进入handler模式,特权级别
    2 s* r0 u- g* e8 @6 \: y  f: Z

  85. " k. S6 k' S* i& |8 n* t& o$ p
  86.   /* Check Thread mode privilege status */+ k- l1 F1 a3 M! T
  87.   if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED): Q% `3 Z: C5 L& `6 W+ D9 a* B
  88.   {& V  \$ F2 o$ h  x( a& |
  89.     /* Thread mode has privileged access  */5 s; e6 c2 ^4 h' @/ v6 C, Y( h
  90.     ThreadMode = THREAD_MODE_PRIVILEGED;  //应该是特权级别: }& M4 U6 E7 N( n; j. R1 b- V
  91.   }; u1 ?& L# Z7 E* I
  92.   else. |8 j, K) x, ?+ g* H+ e, o5 s
  93.   {
    6 p7 i7 }- U5 O1 y- V5 B% [* M9 }
  94.     /* Thread mode has unprivileged access*/
    6 g2 w" _+ p& S! X2 T0 g& t
  95.     ThreadMode = THREAD_MODE_UNPRIVILEGED;1 ?# p3 |: [: A, P6 `
  96.   }% ]3 ^# x$ }8 X4 i, Z

  97. # e7 H, }/ F' B0 R% H; w* v
  98.   while (1)& W. [0 E" L* z" p
  99.   {0 X# o: e1 R) ]3 w
  100.   }1 g0 _6 y; y# f
  101. }
复制代码
% W+ u% w7 Y0 _6 Q  z
2. 暂时不明白这个程序什么用途,只是学习的过程中遇到了,拿出来研究一下。
Cortex-M3处理器支持两种处理器的操作模式,还支持两级特权操作。
$ u3 q. D: c7 S  K& `两种操作模式分别为:处理者模式(handler mode)和线程模式(thread mode)。引入两个模式的本意,是用于区别普通应用程序的代码和异常服务例程的代码——包括中断服务例程的代码。Cortex-M3的另一个侧面则是特权的分级——特权级和用户级。这可以提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。处理器支持两种特权级,这也是一个基本的安全模型。
3. 在CM3运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级;但是异常服务例程必须在特权级下执行。复位后,处理器默认进入线程模式,特权极访问。在特权级下,程序可以访问所有范围的存储器(如果有MPU,还要在MPU规定的禁地之外),并且可以执行所有指令。
在特权级下的程序可以为所欲为,但也可能会把自己给玩进去——切换到用户级。一旦进入用户级,再想回来就得走“法律程序”了——用户级的程序不能简简单单地试图改写CONTROL寄存器就回到特权级,它必须先“申诉”:执行一条系统调用指令(SVC)。这会触发SVC异常,然后由异常服务例程(通常是操作系统的一部分)接管,如果批准了进入,则异常服务例程修改CONTROL寄存器,才能在用户级的线程模式下重新进入特权级。事实上,从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处理器总是先切换入特权级,并且在异常服务例程执行完毕退出时
4.如果根据下表和上面解释重新看代码的话,应该很清楚了。
2 s, V, J( Y5 l9 X) V2 R: M  W
1300009-20171222170030818-1131604041.jpg

! A0 C& M6 g; s7 x9 X
5. 在看下CONTROL寄存器介绍
* A' h7 v3 t: Z
1300009-20171222170243725-510842683.jpg
8 S, m! @8 {4 B5 b
6. 如此一来,基本搞明白了。
: `' H9 ^6 Y" @* C
收藏 评论0 发布时间:2022-1-29 13:57

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版