|
1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量。 - #include "stm32f10x_lib.h"( D4 |! W+ M) h* ~" w# _# L4 l
- #define SP_PROCESS_SIZE 0x200 /* Process stack size */3 j9 P7 Q8 Q( b* s# ^
- #define SP_PROCESS 0x02 /* Process stack */
+ t6 D7 R8 ]' A - #define SP_MAIN 0x00 /* Main stack */
5 P7 Y7 R& u% `0 X- i) e" s" O - #define THREAD_MODE_PRIVILEGED 0x00 /* Thread mode has privileged access */
7 }) L$ F- j2 l" V+ U - #define THREAD_MODE_UNPRIVILEGED 0x01 /* Thread mode has unprivileged access */
: L. v" n0 C% z6 B' r( v* e- } - 7 b% \) ?- z6 m" Y9 w
- ErrorStatus HSEStartUpStatus;' ?* J. N$ L& i" O8 z7 [1 o
- vu8 PSPMemAlloc[SP_PROCESS_SIZE];
# e/ E9 `* M9 T. A5 s - vu32 Index = 0, PSPValue = 0, CurrentStack = 0, ThreadMode = 0;* j8 K2 \+ e8 f) P9 f9 U
- ; I' c& h6 S# u: N0 @! N5 x
- /* Private function prototypes -----------------------------------------------*/
3 `$ N2 T2 c' Q+ ?3 Z - void RCC_Configuration(void);. x' P& \$ H* S# a y9 P9 P
- void NVIC_Configuration(void);8 n+ V' a5 J& B& q& u
- 3 f3 n* \' W6 j( N+ F
) _) D* x. z5 s0 e* i- int main(void)5 J6 z# M& ^3 N5 s; X' K4 T
- {
g) w4 n! k$ k4 t- ^, H. } - #ifdef DEBUG" a; D. C- c0 d% ~
- debug();
" s2 m+ r: }$ D E: i - #endif2 @+ K) H* G* z* u& P6 b/ N
/ W8 a& K# q4 _ X+ s1 ~! w x- //时钟配置
" b" o; H0 J, x; {7 a/ w - RCC_Configuration();
! J) T( \- D+ n4 X: ?2 O; c - 7 @& B3 F8 P" s$ `2 h/ G
- //中断向量表配置) P7 E" l u( q+ w
- NVIC_Configuration();
" q0 d& h& B4 h! r
$ K9 v7 D- C7 }& S- //STM32有一个主堆栈指针MSP,和线程堆栈指针PSP,把进程堆栈指针指向这个数组的高地址,因为堆栈指针是向下增长的, y1 Q' x$ H; L. K& L. J
- /* Switch Thread mode Stack from Main to Process -----------------------------*/
8 t) E7 T# c+ Q1 I- H - /* Initialize memory reserved for Process Stack */* ]/ @: G( p! K( `- g
- for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
6 t" B( N) p& t) L4 q - {
) R& a# T, j! C! u/ D - PSPMemAlloc[Index] = 0x00;
# H, c% h `+ ~/ C8 Q6 n - }
; q; s; z- `, M. m" k - //系统上电,是在线程模式,特权级别下,所以可以修改CONTROL寄存器,这个寄存器选择特权级和用户级,还有系统选哪个堆栈指针0 ?2 ^" H0 [, n" B1 m( m" F2 I, r9 J
- /* Set Process stack value */
& V( m3 A' p. ?( @( c - __MSR_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE);
) e( g! ?7 P4 [- C+ ? - //选择线程堆栈作为线程模式的堆栈,有点绕口
% @# b! F8 j7 {+ s' }% E - /* Select Process Stack as Thread mode Stack */
f! Z6 ], i1 N1 \# f - __MSR_CONTROL(SP_PROCESS);
. D H' k: S; ~7 T0 H - 0 B U0 ^, B4 M. g" A; W
- /* Get the Thread mode stack used */' k. a: M5 x8 E4 H' \& _
- if((__MRS_CONTROL() & 0x02) == SP_MAIN)
6 n/ |0 a D8 b( s. t* K5 w - {: ?9 A H( G$ p9 d: I
- /* Main stack is used as the current stack */6 q' |. Z' C) H3 |1 z* f
- CurrentStack = SP_MAIN;
* D: P. {+ r4 x& o2 D - }/ k$ \! b6 I; H+ v1 ~7 y, X r& G
- else* ]* B4 h/ X3 I0 x; o4 z
- {- O c) s/ S4 A/ U
- /* Process stack is used as the current stack */
* M# Q. }8 T; D/ M3 @ - CurrentStack = SP_PROCESS;9 k8 M% r6 W5 U
- % }7 `7 D4 Y# t6 b0 V3 B
- /* Get process stack pointer value */
+ A" M2 Q. @- @7 T! }' n5 s - PSPValue = __MRS_PSP();
* B5 D) G8 L/ z* e - }, p; u4 m4 u9 g. M, e
- ' L. w7 ^$ Z3 y$ B, n* r1 m0 a: A
- /* Switch Thread mode from privileged to unprivileged ------------------------*//切换线程模式到非特权' y V G) S9 v0 z9 m# W, E. L0 v
- /* Thread mode has unprivileged access */* c; N8 u& @+ Z, \
- __MSR_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);" @/ Z5 y3 ^3 }3 L! E2 V2 r
- /* Unprivileged access mainly affect ability to:
( \6 R: R0 ~3 y! Z: _( L J. M! g - - Use or not use certain instructions such as MSR fields' p, Q+ h1 d# o
- - Access System Control Space (SCS) registers such as NVIC and SysTick */8 ?* d# ~/ ]% Z2 P+ @7 z
. M- }; ?4 k% s( u0 c- /* Check Thread mode privilege status */ //检查当前是特权还是用户级别' d! O6 B# K0 J, U
- if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)7 `+ V- A% _/ F3 H [/ g2 C
- {
; q1 e0 M( G9 P - /* Thread mode has privileged access */- S: { f/ B' t B
- ThreadMode = THREAD_MODE_PRIVILEGED;
5 z! g, l9 H% O- l* W - }
2 Y5 `. l# H# ~/ g+ e2 V' [ B& _ - else
4 h2 V+ Z, h$ ?: _ - {
+ z/ Z8 u! S ?1 G; P - /* Thread mode has unprivileged access*/4 H0 @4 y2 x t* l8 l8 j) x
- ThreadMode = THREAD_MODE_UNPRIVILEGED; //应该是用户级别
: F! F9 F* l* G - }7 c& r) c4 _ Y. r$ k( M
- 5 c! U3 ]2 y& H
- /* Switch back Thread mode from unprivileged to privileged -------------------*/ //切换到特权模式
: I% \" j4 g8 S9 Q5 ~ - /* Try to switch back Thread mode to privileged (Not possible, this can be
' T8 J; B; g4 i# c1 q4 ` - done only in Handler mode) */
9 m( d! t# L7 e, k; l) S2 ` - __MSR_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);
5 H: y" m& S8 i T* a, u' L# p3 d
& l9 C3 V; _1 h, c" S9 g- /* Generate a system call exception, and in the ISR switch back Thread mode* \$ d U$ k$ C/ b8 j( f, q& |
- to privileged */
+ l* w' K/ l! c" _# O$ T+ D* n - __SVC(); //产生中断,进入handler模式,特权级别
2 s* r0 u- g* e8 @6 \: y f: Z
" k. S6 k' S* i& |8 n* t& o$ p- /* Check Thread mode privilege status */+ k- l1 F1 a3 M! T
- if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED): Q% `3 Z: C5 L& `6 W+ D9 a* B
- {& V \$ F2 o$ h x( a& |
- /* Thread mode has privileged access */5 s; e6 c2 ^4 h' @/ v6 C, Y( h
- ThreadMode = THREAD_MODE_PRIVILEGED; //应该是特权级别: }& M4 U6 E7 N( n; j. R1 b- V
- }; u1 ?& L# Z7 E* I
- else. |8 j, K) x, ?+ g* H+ e, o5 s
- {
6 p7 i7 }- U5 O1 y- V5 B% [* M9 } - /* Thread mode has unprivileged access*/
6 g2 w" _+ p& S! X2 T0 g& t - ThreadMode = THREAD_MODE_UNPRIVILEGED;1 ?# p3 |: [: A, P6 `
- }% ]3 ^# x$ }8 X4 i, Z
# e7 H, }/ F' B0 R% H; w* v- while (1)& W. [0 E" L* z" p
- {0 X# o: e1 R) ]3 w
- }1 g0 _6 y; y# f
- }
复制代码 % 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
! A0 C& M6 g; s7 x9 X
5. 在看下CONTROL寄存器介绍 * A' h7 v3 t: Z
8 S, m! @8 {4 B5 b
6. 如此一来,基本搞明白了。 : `' H9 ^6 Y" @* C
|