题目起跟上一篇很接近啊。本文主要说的就是安全区的代码怎么去操作非安全区的资源。
) j& L: m( h+ {9 [8 T安全区可以操作非安全区资源,安全区可以调用非安全区的代码。
/ h2 g! S$ T' { G; ~工程设置跟上一个一样,还是俩小灯,PH6属于非安全区资源,PH7属于安全区资源。
5 y, `6 A- e: U+ O. o" H
& t: c+ S; _; F: `( n
首先我们试一下直接操作寄存器,接着上次的程序来。
: X f! r s! X. B- A& F2 x这次程序是非安全区调用安全区代码,然后安全区代码操作非安全区的小灯,嗯,听起来很绕。
1 F$ n0 f1 e& W' S2 [; e# q. b非安全区 main函数里
2 X( c' Q" }- H! T; \' ~8 \% K- /* USER CODE BEGIN WHILE */9 v5 s3 V% V! F0 S* x K
- while (1)
8 Z& K$ i4 ]2 b) Z; L: Z; l( ^( d, X$ N z - {
A5 l/ ~/ S' c4 u4 O6 p# W. D - LED_toggle_S();
# x6 [* g- B R7 g% J: J& ] - HAL_Delay(1000);
8 z) p2 w" D9 {8 p* b3 e1 h - /* USER CODE END WHILE */
9 k! l$ I7 G' T: Y# e7 o - V0 t, W6 }; w' b( ^
- /* USER CODE BEGIN 3 */% D- b1 Y: T- l8 B& J$ l
- }
! l. v8 Q) {+ ~! P H+ q/ q - /* USER CODE END 3 */
复制代码 . D D6 G3 @, w
安全区代码
( K. @# g9 C; @; |5 U- void LED_toggle_S(void) CMSE_NS_ENTRY
3 ~8 C3 n( ^+ n" b" h/ h1 K* v* h/ F - {- k- v& W7 w1 t, B# }) F
- HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_6);
: U' h1 I# ~6 ~% M& t6 ^ - }
复制代码
) ]# r2 {/ E* n/ _8 y编译下载,红灯开始正常闪烁。1 F- @0 _- V R9 \3 i" c
一切正常。
7 ^2 J5 {, I7 S' u1 J9 h接下来是安全区代码调用非安全区函数,好像有点怪,如果安全区代码调用非安全区代码,同时非安全区代码也调用安全区代码,是不是就出现互相依赖的问题了?所以它并不是直接调用的函数,因为安全区代码对非安全区所有的资源都有操作权限,那我就直接操作地址就好了啊,直接访问非安全区代码的地址,调用它(实际使用中还需要点修饰)。接着刚才的程序。
1 v- }- ^2 E3 {4 x, @# U. M非安全区
4 j- [) j0 T5 f6 T. D" Z$ V- void LED_toggle_NS(void) __attribute((section(".ARM.__at_0x8101000")));
+ K. X9 D2 Y" W0 g - 5 |# Y( P8 p1 `5 {* L& A' }# F
- void LED_toggle_NS(void)% i1 o; q" w1 L
- {
( W8 G) }8 S2 Y7 c0 J; B2 O' s( H6 q - HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_6);
/ G" g8 @: f5 m T - }
复制代码
7 p$ _2 Y& R/ U4 t$ L2 L非安全区 main函数里! D: j/ b3 D( u% [3 h
- /* USER CODE BEGIN WHILE */
. B! |: X6 V# s0 z - while (1)
6 l6 v+ x# }1 Y, ^: _3 p# i - {
9 G( P. g, l9 q' S0 m - LED_toggle_S();0 V% A9 t+ Z2 C# }( o z
- HAL_Delay(1000);
& p7 W9 j- x5 R& G4 f! Q2 ^1 g - /* USER CODE END WHILE */
: w9 @. N& o; N& ]+ Y# |+ ?
8 D2 ] w) Q v* Z$ z# I3 f: O- /* USER CODE BEGIN 3 */
: N' E* D) M. _ - }8 b" v% s& h; \6 S) a. p1 {4 {
- /* USER CODE END 3 */2 N6 @+ x1 r3 M) e! B2 N
复制代码
. m! `* O+ @" J# f- v0 y创建一个操作小灯的代码,并编译到0x8101000地址上。
( c( Y& b/ O& k2 t7 @ G) \6 V7 O, b安全区代码
* o4 c& F3 D N- n; E* ~- void LED_toggle_S(void) CMSE_NS_ENTRY' `) f/ B- j9 j5 O3 I( `8 [
- {
( g- y9 N# q, M: B9 U. q8 O - funcptr_NS LED_toggle_NS;: F& y8 G& w' `' M' D
- LED_toggle_NS = (funcptr_NS)0x8101000;: v9 P/ C# N$ p" r5 Q
- LED_toggle_NS();
0 U" C( b+ q. ~2 s4 T' m - }
复制代码 ( ~* ^* p) \ x
就是调用了非安全区的程序,嗯,这是一个非安全区代码调用安全区代码,然后安全区代码调用非安全区代码,然后通过操作非安全区程序控制小灯,嗯,绕口令越来越熟练了。
1 E4 z9 b3 n1 M2 }. _3 C编译下载,红灯开始正常闪烁。: G+ b. ]; m Q0 S0 @4 o, _1 J+ b
$ E1 ]4 d; |1 ~, Q
funcptr_NS 是ST给我们提供的一个定义好的接口,不光上面一种写法。) i4 _9 j, i& G" ]7 w
5 O- U' Y2 X1 W& t2 z* i善良守序
) U& E* P( o3 P5 u! n5 g F4 ~7 j1 R& E- funcptr_NS LED_toggle_NS;7 Q) I4 n0 z$ x5 e
- LED_toggle_NS = (funcptr_NS)0x8101000;
5 w! u" t7 t' ]. j, l1 Y! X3 J - LED_toggle_NS();
复制代码
' t0 L. x6 e) O. D8 H绝对中立3 H0 ^: w& j" w, Q' l4 C
- ((funcptr_NS)0x8101000)();
复制代码 ! y# _1 _2 a! q# F! r
混乱邪恶& s1 ~" y" P* w% n. I: {
- ((void __attribute((cmse_nonsecure_call))(*)(void))0x8101000)();
复制代码 & R) h. b9 O4 I, Y# P: j
全展开确实太刺激了点,哈哈。
5 {0 X6 P) \2 T" |; @, F2 @4 l! B4 P5 v4 Q; Z8 `: f
|