|
1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量。 - #include "stm32f10x_lib.h"
5 S" z+ B' ^) C+ |: { - #define SP_PROCESS_SIZE 0x200 /* Process stack size */6 R: _( ?# y: c) h' Y$ |5 f
- #define SP_PROCESS 0x02 /* Process stack */; k: [" M/ x6 E3 N5 N% p8 f
- #define SP_MAIN 0x00 /* Main stack */
. O- H8 x; ^7 I6 V/ A6 ^8 B4 Y - #define THREAD_MODE_PRIVILEGED 0x00 /* Thread mode has privileged access */( x8 M) D! N: V0 F ~3 w- P
- #define THREAD_MODE_UNPRIVILEGED 0x01 /* Thread mode has unprivileged access */0 X1 W) u8 Y9 x8 G* R4 I1 o
9 T8 u5 W1 P& I+ H1 |! q- ErrorStatus HSEStartUpStatus;
/ v4 A [$ G; x3 S& g0 b8 i- f4 g - vu8 PSPMemAlloc[SP_PROCESS_SIZE];
( Q! [, v, ]8 w3 o& l - vu32 Index = 0, PSPValue = 0, CurrentStack = 0, ThreadMode = 0;9 S7 [( L8 G$ B- D7 }, [* \
$ y& o! ~! P& w6 @( n! Z9 ~' h/ r- /* Private function prototypes -----------------------------------------------*/
2 a3 ?) w; y4 @. y( ? - void RCC_Configuration(void); A, c) `& x: r
- void NVIC_Configuration(void);* ^$ T( ?. ]: d. J' k' e
- / K9 N N0 i2 ?' {" v3 K0 m5 Y9 R
, D0 F0 ]% i' T! l4 Q0 l- int main(void)
6 R4 m- v6 e3 b2 y- l+ q, H. k/ t: R$ q - {) C6 b0 d4 c& r. ]2 Q$ ?" ~/ G) L2 L+ N, g
- #ifdef DEBUG
& f4 @+ Y$ M/ Z( W! `# O - debug();
. n2 y. e! g% U( v - #endif$ y+ W" m. r1 h: z+ |, G2 ?
- 6 @) g/ I$ b( O# Q% {. v' X
- //时钟配置
i- r4 l) L ]- q) e - RCC_Configuration();
7 K: t: M9 z- d! {0 m - * X; q, @) t8 [! T" E. f
- //中断向量表配置/ C- R- J0 b2 |0 e! W
- NVIC_Configuration();
2 E0 y4 B9 [# K" a2 G9 d5 u - 5 j5 P5 |! D r, D8 Q
- //STM32有一个主堆栈指针MSP,和线程堆栈指针PSP,把进程堆栈指针指向这个数组的高地址,因为堆栈指针是向下增长的
! i& O" H; Y3 d5 `- [0 Q - /* Switch Thread mode Stack from Main to Process -----------------------------*/
( ]' s! E# S4 b5 t/ w; m* U9 r3 c; W - /* Initialize memory reserved for Process Stack */8 }) A$ A: O& N7 |/ E. d
- for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
* E5 c! M0 I6 @% b - {
e; C* h" ]( `7 r- [ - PSPMemAlloc[Index] = 0x00;4 X# N. G( Z6 ?- x: b
- }
2 H9 D2 ?! ^8 e7 s - //系统上电,是在线程模式,特权级别下,所以可以修改CONTROL寄存器,这个寄存器选择特权级和用户级,还有系统选哪个堆栈指针
! d& k* ~" Y3 [) F$ f5 S M. G - /* Set Process stack value */
) L" s/ \6 |5 K: r6 r - __MSR_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE);
7 A) K4 _4 n/ h ? - //选择线程堆栈作为线程模式的堆栈,有点绕口
~; E7 d- |( X& b0 t: I9 u* _/ A, j - /* Select Process Stack as Thread mode Stack */
6 p4 K$ y" G" t+ z - __MSR_CONTROL(SP_PROCESS);
1 F6 J n7 C8 \/ l- j - 4 c5 p4 M- I8 q9 l4 @
- /* Get the Thread mode stack used */
! O1 v3 b6 }: u$ E+ z% ~; G# q - if((__MRS_CONTROL() & 0x02) == SP_MAIN)
) f3 q$ z' M% j! j8 y8 a - {
8 s8 y0 l' F O1 i6 _7 @0 n - /* Main stack is used as the current stack */$ z# @0 c. D# W3 k/ T
- CurrentStack = SP_MAIN;7 H* h, ?# ?- m1 G# @3 U, a, B
- }( e' @ I& s* z5 G; J
- else
. s1 s/ ?8 w/ v9 m& ^3 g - {
- D; q/ F9 i1 O% Y - /* Process stack is used as the current stack */7 M; l0 z0 `/ b' @$ p/ j* m
- CurrentStack = SP_PROCESS;
8 w$ s n5 Z ]3 h B. \% k
- N. p1 V- m8 g- /* Get process stack pointer value */
2 v9 W5 g5 b |) q; g6 \0 R - PSPValue = __MRS_PSP();' L9 K3 D# \. N1 L8 J$ d
- }0 J3 D8 F- i- ?* w- v
% T* N2 s1 m4 U' i* [- /* Switch Thread mode from privileged to unprivileged ------------------------*//切换线程模式到非特权
- A5 C( ]' H; ^0 v - /* Thread mode has unprivileged access */
6 S# D+ [3 G0 _ - __MSR_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);0 M8 {! h r2 Z4 @% f9 C" t7 O
- /* Unprivileged access mainly affect ability to:
) X) n# H7 B% t- p( F( P a- D - - Use or not use certain instructions such as MSR fields
9 R# O( U" v' k! r - - Access System Control Space (SCS) registers such as NVIC and SysTick */
+ j% L' t1 q& e8 A
- u. G( P5 D* `1 T7 w* j- N* |6 I- /* Check Thread mode privilege status */ //检查当前是特权还是用户级别
! }! Q7 \2 D* \. O: P/ z - if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)/ i( R1 I! D, Z) X4 X
- {, d$ `$ m* X/ [: x C
- /* Thread mode has privileged access */
% _. L% {5 f% K( _* |1 }: g0 I - ThreadMode = THREAD_MODE_PRIVILEGED;2 ^) i" g' y) ~. o. J! b8 j
- }& P! G, @4 a& r; [ {8 X# K" q
- else4 T' g+ E. ~7 z; W! Z4 T
- {2 C* q N/ U* c" f2 E( H S5 G
- /* Thread mode has unprivileged access*/
+ L/ O( G; i1 } - ThreadMode = THREAD_MODE_UNPRIVILEGED; //应该是用户级别
% ?: q( ?2 y, N - }
+ f& ^" o' I2 o7 Y) J, X2 R4 g/ N - 2 u( Y) y2 w: U1 c
- /* Switch back Thread mode from unprivileged to privileged -------------------*/ //切换到特权模式: F& ~$ o" o- O- v( v* N+ c% n
- /* Try to switch back Thread mode to privileged (Not possible, this can be. `4 d; S: p3 [3 G. S
- done only in Handler mode) */
9 T3 \3 r4 n, `) ]& P- e) i: I - __MSR_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);
; ?. U) ^7 i0 I% q8 ?! `' f - 4 B+ p3 m% a# F8 }8 Z6 M
- /* Generate a system call exception, and in the ISR switch back Thread mode4 f$ N! l7 A% K }
- to privileged */
% } y/ g# ]: q9 }4 G$ u - __SVC(); //产生中断,进入handler模式,特权级别7 T2 f! n Z- a
; Y2 b0 a& \ }9 m r) D- /* Check Thread mode privilege status */' O7 o% K' _$ b. {* d& L
- if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
" g1 x5 t4 i z5 ~ Y6 ^: a - {
4 _# {4 F6 l& v! p - /* Thread mode has privileged access */
& ^! p) F% L# A7 V e9 K - ThreadMode = THREAD_MODE_PRIVILEGED; //应该是特权级别: w4 V! a! s* m. m" I% ~8 _$ I
- }- F, Q, T% P- @' k* A* ]
- else
+ u [" K0 j) }5 K1 ~9 G8 J0 p6 X3 s - {
+ l* ^# V. V; t& Q% f - /* Thread mode has unprivileged access*/
; v4 O0 z( K* y' [' o& E - ThreadMode = THREAD_MODE_UNPRIVILEGED;* v+ W' _" r7 J9 y- R; k
- }
/ R$ R/ @, S' D6 B. Q7 I
2 {2 T6 I% E2 E$ u* V- while (1)
K) n' _/ ^; C8 [4 ?8 I7 U& U - {
( T4 n- t" _0 H- a - }
5 p' S0 _; E: ^3 n - }
复制代码 - g3 Y: `; y) l- N1 p1 w! F
2. 暂时不明白这个程序什么用途,只是学习的过程中遇到了,拿出来研究一下。 Cortex-M3处理器支持两种处理器的操作模式,还支持两级特权操作。& P$ M/ s$ m) j+ p
两种操作模式分别为:处理者模式(handler mode)和线程模式(thread mode)。引入两个模式的本意,是用于区别普通应用程序的代码和异常服务例程的代码——包括中断服务例程的代码。Cortex-M3的另一个侧面则是特权的分级——特权级和用户级。这可以提供一种存储器访问的保护机制,使得普通的用户程序代码不能意外地,甚至是恶意地执行涉及到要害的操作。处理器支持两种特权级,这也是一个基本的安全模型。 3. 在CM3运行主应用程序时(线程模式),既可以使用特权级,也可以使用用户级;但是异常服务例程必须在特权级下执行。复位后,处理器默认进入线程模式,特权极访问。在特权级下,程序可以访问所有范围的存储器(如果有MPU,还要在MPU规定的禁地之外),并且可以执行所有指令。 在特权级下的程序可以为所欲为,但也可能会把自己给玩进去——切换到用户级。一旦进入用户级,再想回来就得走“法律程序”了——用户级的程序不能简简单单地试图改写CONTROL寄存器就回到特权级,它必须先“申诉”:执行一条系统调用指令(SVC)。这会触发SVC异常,然后由异常服务例程(通常是操作系统的一部分)接管,如果批准了进入,则异常服务例程修改CONTROL寄存器,才能在用户级的线程模式下重新进入特权级。事实上,从用户级到特权级的唯一途径就是异常:如果在程序执行过程中触发了一个异常,处理器总是先切换入特权级,并且在异常服务例程执行完毕退出时 4.如果根据下表和上面解释重新看代码的话,应该很清楚了。 2 n% k& g: _* F
, {. z" P- ~* h, g" P @
5. 在看下CONTROL寄存器介绍
1 P7 n. B) k. X( Z1 {
) e C9 w' Y- d2 M5 H" _
6. 如此一来,基本搞明白了。
3 I9 r+ K0 |5 B |