题目起跟上一篇很接近啊。本文主要说的就是安全区的代码怎么去操作非安全区的资源。( R/ g ~. |) h% w6 Q( ]
安全区可以操作非安全区资源,安全区可以调用非安全区的代码。
8 |+ J3 G, w: x. D5 i6 H工程设置跟上一个一样,还是俩小灯,PH6属于非安全区资源,PH7属于安全区资源。& P+ e8 Z' v% t" |3 M) l" m
- o" d& r, `' ]; R, E; G
首先我们试一下直接操作寄存器,接着上次的程序来。
& V, U( J/ `- ]+ Y这次程序是非安全区调用安全区代码,然后安全区代码操作非安全区的小灯,嗯,听起来很绕。
* s, C! f0 }* s5 k/ s9 V) }$ a非安全区 main函数里8 _' h# S+ S' E+ d
- /* USER CODE BEGIN WHILE */+ Z/ i; O# T& G
- while (1)
( e( C6 q: Q' i% N - {
- \. ?% A. }5 A, D5 H" B" n$ ? - LED_toggle_S();1 m. n) Z9 D" x1 _
- HAL_Delay(1000);9 U' p( X4 x- A/ P. J9 `( r5 w' V
- /* USER CODE END WHILE */
1 Z2 |- }3 v, z C
( ?; { p M; s4 U7 n* U: o9 u% ?- /* USER CODE BEGIN 3 */
5 B/ d7 k- n' t( e - }
7 q& Y$ I1 Z* M* I1 R5 y - /* USER CODE END 3 */
复制代码
9 a3 B: B: Y- u( s1 ~8 v- Z9 Q安全区代码
2 B. l9 ]: c/ C9 V- void LED_toggle_S(void) CMSE_NS_ENTRY
( T1 `. |2 A6 @ V' m) w - {) }4 S6 W/ C2 z2 U7 P7 j
- HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_6);5 F2 n3 j8 _9 C$ b5 K0 H
- }
复制代码 ; T9 F$ \- k5 ]% x) ^7 I- `. ~
编译下载,红灯开始正常闪烁。+ r8 Q L; r. ~# V, I+ ~1 T
一切正常。
( j5 {* E' _: T. p! C( r6 t- c( D' Y接下来是安全区代码调用非安全区函数,好像有点怪,如果安全区代码调用非安全区代码,同时非安全区代码也调用安全区代码,是不是就出现互相依赖的问题了?所以它并不是直接调用的函数,因为安全区代码对非安全区所有的资源都有操作权限,那我就直接操作地址就好了啊,直接访问非安全区代码的地址,调用它(实际使用中还需要点修饰)。接着刚才的程序。
2 Z0 L. h( V- j; C6 [5 j& D非安全区
3 Q0 P7 @- N2 v6 |' i- void LED_toggle_NS(void) __attribute((section(".ARM.__at_0x8101000")));
n8 T0 A3 Z, a# M
6 A5 f0 e r7 N* t- void LED_toggle_NS(void)
. g8 d9 p8 Y# g' H, ` - {* p# z8 G; A, M
- HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_6);: H$ P$ _4 E3 K& S& c, G2 U
- }
复制代码 ' B- W; N$ g) W0 j, ?
非安全区 main函数里% Z m; m& I* c- J2 {2 R9 m
- /* USER CODE BEGIN WHILE */' U1 j6 D) r+ |! g
- while (1)+ [: i4 q2 [7 {1 c8 s
- {! X% R& \, z4 ]1 w5 t
- LED_toggle_S();
' }3 B. G: b; y- W, y7 Y" o - HAL_Delay(1000);6 j G9 _4 s# X- F. [6 h
- /* USER CODE END WHILE */) G# G* p( K' A4 h3 B" S
- ! V/ @' A2 V4 E
- /* USER CODE BEGIN 3 */* i0 ^: G# o- }, P1 ^
- }1 x8 I" y' A3 t" M
- /* USER CODE END 3 */
2 h( n; f4 G/ e: I4 }
复制代码
& t+ C+ O* F; a& [创建一个操作小灯的代码,并编译到0x8101000地址上。* S8 U3 Z+ {" q* R9 ^! F4 C
安全区代码
8 M6 u0 r, C( V6 W: z+ l- void LED_toggle_S(void) CMSE_NS_ENTRY
' ?$ j8 L0 h/ `! }8 P/ D' U0 Q1 ? - {* ~( O! V: e: { }& k+ ~
- funcptr_NS LED_toggle_NS;( d5 ` f: Y6 C# X
- LED_toggle_NS = (funcptr_NS)0x8101000;6 u( r9 @! k0 j. w+ c% o+ q
- LED_toggle_NS();# x9 o) `6 k4 n
- }
复制代码
+ ^7 U! ~2 x- q) c4 q就是调用了非安全区的程序,嗯,这是一个非安全区代码调用安全区代码,然后安全区代码调用非安全区代码,然后通过操作非安全区程序控制小灯,嗯,绕口令越来越熟练了。$ E1 a& O5 H" r. q+ q
编译下载,红灯开始正常闪烁。" t8 }- e' G2 |/ e0 J
3 D* J- j0 Y7 ]+ d, N( ~: C9 g
funcptr_NS 是ST给我们提供的一个定义好的接口,不光上面一种写法。
& w7 r( b. D) M4 ~/ s" k
( w" {) `4 u3 k% B4 t; _$ m善良守序
' P9 _3 ]0 Y1 e0 R# G5 n- t- funcptr_NS LED_toggle_NS;
* ^# e5 q; U: r. c, P - LED_toggle_NS = (funcptr_NS)0x8101000;
5 L$ E+ ?0 @3 A$ \- o - LED_toggle_NS();
复制代码
% Y$ j: c& K$ J& l' Q2 E" s绝对中立
1 n+ Z- f- M- S" _- ((funcptr_NS)0x8101000)();
复制代码
: A4 v$ t) r5 z混乱邪恶* R+ N Y& [( i ^
- ((void __attribute((cmse_nonsecure_call))(*)(void))0x8101000)();
复制代码 # X6 w, ?$ E: `: T, R: u2 |
全展开确实太刺激了点,哈哈。1 q, y9 y0 L5 e
$ o; \( ^- E2 e |
8 ~+ D3 O( K2 \