27.1 初学者重要提示
o+ A1 I- b3 M7 b 学习本章节前,务必优先学习了解TCM,SRAM等五块内存区的基础知识,比较重要。
( O- D( e& g: @( N, s7 c 将RTX5系统的动态内存管理整理了出来,可以同时管理多个分区。如果其它RTOS中使用,记得做互斥保护或者加个调度锁均可。* A- A1 o# `# `6 `2 ?1 @+ M, H( ?& s
支持动态内存使用情况统计。
5 t) C; N! [$ s( S27.2 动态内存管理移植
6 Z0 l/ M/ Z9 y: L, [移植比较简单,仅需添加两个文件到工程即可。: }7 K9 p; R4 c- Y
& L8 m% G D- T) P0 T
27.2.1 MDK版的移植1 m+ L8 a) Q% G: e# P5 c
第1步,添加如下两个文件到MDK中
1 ?/ h9 o5 j4 p" r注,以本章配套例子为例,这两个文件的路径\User\malloc。
! T, @/ k1 r) q2 y+ m2 A
# J G0 X: u) @) ?8 _, y" c0 X+ @2 |! D% \
+ T6 U4 i+ F7 c; c9 ], Y
第2步,添加路径。
. T8 }3 a. V* u6 A% h( f4 G) q/ E( r6 p( A. a
* b6 g v9 s. d1 b$ o
- [4 w% T( g# A I/ R- d6 n
第3步,添加头文件。
" {0 J$ a9 Z/ w1 S: Y/ f9 E如果哪个源文件要用到动态内存,包含rtx_lib.h即可,本章配套例子是直接将其放在了bsp.h文件里面,哪个源文件要用到动态内存,直接包含bsp.h头文件即可。% O6 Y( i; t# \, s
3 l: x J$ K* D; t+ Z( z通过这简单的三步就完成了MDK的移植。/ d& y6 e* v' f- V9 S5 y
, h% `* M; w, |' s) Q6 }" @27.2.2 IAR版的移植) p1 ]7 z. \8 P! N) Q/ j9 v9 f; u- h
第1步,添加如下两个文件到IAR中
& n( W) Y8 ^* G6 d注,以本章配套例子为例,这两个文件的路径\User\malloc。
: j" z9 ]+ ^. D: ?" p- o! ?7 F2 V# L% {8 x1 d/ ~% d1 v. T# c$ h! i
7 ?# n( o; E+ Y/ ~& A% ]7 U$ V; `) N; O
第2步,添加路径。" a4 o" u- U6 @9 F4 C
/ `# \. ]2 F1 H! P; y7 d
# e4 V' s3 O! Z7 }
3 T5 D" v/ E9 a4 U+ k0 Y 第3步,添加头文件。
4 q$ e" h* ]! W0 U2 c如果哪个源文件要用到动态内存,包含rtx_lib.h即可,本章配套例子是直接将其放在了bsp.h文件里面,哪个源文件要用到动态内存,直接包含bsp.h头文件即可。
& U; o2 [, ~5 D. F3 _% A' H' V- t7 S$ a' f6 P8 s+ ~
通过这简单的三步就完成了IAR的移植。
7 ^+ X$ k, a& a b4 Q/ I2 g
2 E8 _2 F* \3 J/ u8 R E! Y27.3 动态内存的使用方法& s" z) }% p" Q( g; m) f
下面分别以MDK和IAR为例进行说明:. W2 U; x+ D2 I
; T% \7 z& H3 T6 z9 a; h6 I. N27.3.1 MDK上的动态内存用法
, u' |: Q% H& w2 m" D4 u5 I 定义动态内存区4 K" |5 X8 k: M! J4 j, I2 m, u/ ]% ?) K
比如当前的主RAM用的DTCM,我们就可以直接定义一块大的数组作为动态内存空间:6 t: n K9 o) Q* U7 y3 i4 k
+ T) z9 Z0 J* n# p9 k8 M; ^# e
- /* DTCM, 64KB */
$ q# O; k; U/ f N& |- ^3 C - /* 用于获取当前使用的空间大小 */
, E4 ?- O+ ?/ Q" M$ A9 G9 X- _ - mem_head_t *DTCMUsed; 8 \; s. }9 I; w+ d( U* Z5 J3 g
- /* 定义为64位变量,首地址是8字节对齐 */
1 {" q: V6 [5 v' D+ z - uint64_t AppMallocDTCM[64*1024/8];
复制代码
7 @5 _* ^7 A* N如果要使用AXI SRAM作为动态内存空间,可以使用__attribute__((at( )))指定地址。8 D' d3 Q$ L' c2 ?
8 {' Z. y* A9 [, w/ h' x1 `5 F+ R9 h- /* D1域, AXI SRAM, 512KB *// I& N- |: D' X
- /* 用于获取当前使用的空间大小 */
$ L. m# v# q; E - mem_head_t *AXISRAMUsed;
' K9 p3 K' m, e. s/ ^3 ~% @ - /* 定义为64位变量,首地址是8字节对齐 */
8 J8 X) T4 X# ?" Q - uint64_t AppMallocAXISRAM[512*1024/8]__attribute__((at(0x24000000)));
复制代码 ) f) H1 |4 s3 U; @$ h" y0 m
初始化动态内存区1 v0 Q0 h) ?4 O& L, |" n y2 m
调用动态内存管理提供的函数osRtxMemoryInit即可做初始化:
6 K$ v# r8 x% |# A+ O
5 |* {" o+ X( m/ p, u5 H2 sosRtxMemoryInit(AppMallocDTCM, sizeof(AppMallocDTCM));
( R" c6 E; T0 b; D3 }osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
, J: D7 G2 o5 D. ^* I$ _: U6 j
* Z( _4 ?9 }: f9 S! A- |0 N 申请动态内存" \ C# o8 X5 [& }8 ^, q
通过函数void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type)做动态内存申请。2 w9 l1 J8 m" X: C' D
" c1 m, n, n- U# h0 W0 ?
第1个参数填写内存区首地址,比如申请的AppMallocDTCM,就填AppMallocDTCM即可。# r6 f/ }- }2 T% G/ `/ f
1 b- P) v( R; O# K7 F6 C
第2个参数填写申请的字节大小,单位字节。
! Q/ l# p. \: F* r; G: E3 T' j
4 L( j' x3 i9 B- o# p+ X第3个参数固定填0即可。' e6 k: j2 x5 M! c5 M# m
7 C/ ~" ?' `9 T, l8 N$ d4 D
返回值是所申请缓冲区的首地址,如果没有空间可用,将返回NULL,这点要特别注意!
- Y4 j$ N5 ~( R
1 E+ J( ]1 e* q1 f. b举个例子:- I0 }# V. L, X0 n9 Z2 b
4 h: R+ O4 ~6 m2 [; Y; H- uint32_t *DTCM_Addres0, *AXISRAM_Addres0;" m9 j/ A! ]5 |" p# n" H$ }/ o
+ i8 k1 ?5 I z1 e) E- /* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
9 ] g9 r' Y7 y+ f" C4 ~% i - DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0); g4 H R: _% O
- DTCMUsed = MemHeadPtr(AppMallocDTCM);
& U; I4 Q: r! P- b2 @; Z6 I) K - printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n", 6 g! Y/ L# @: i3 D# a8 Q
- DTCMUsed->size, DTCMUsed->used);
$ [# f4 o! _1 E# b" |
% A% [" J, K) \# B* b- /* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */ - d4 R6 e' w M; Z
- AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);. o8 B% c+ O/ Z! c$ x! e/ V: T' s
- AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);( s9 k& U5 r( a: a* B
- printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
2 G# G* V* x1 t - AXISRAMUsed->size, AXISRAMUsed->used);
复制代码
: q5 O# n' |8 d申请了空间后,就可以直接使用了。另外注意红色字体部分,通过DTCMUsed->used和AXISRAMUsed->used可以获取当前使用的空间大小。7 P9 e) U: ]# K, i% X! [
& D6 j" F) b# e" Q. S5 p- ^/ ~" d) a
释放动态内存
) } ]: U5 E3 e3 L) D# l通过函数uint32_t osRtxMemoryFree (void *mem, void *block)做动态内存释放。
- Z; `, j; w( I6 P A, `) H; |6 h/ W" z! f: r8 ~ x# S; n
第1个参数填写内存区首地址,比如释放的AppMallocDTCM,就填AppMallocDTCM即可。
( J2 B, ^$ V$ y/ H; V6 S% j! A- S/ z `/ i. h- Q' H6 i7 i
第2个参数填写申请内存时所获取的内存区首地址,这里用于释放。
3 D) z7 T: Z! s6 X; j8 M8 [ c8 ]# p; Z0 j! Z2 O: Y, S6 u( o6 y
返回值,返回1表示成功,返回0表示失败。
/ q2 T: {5 Q1 v+ v( Z* {7 s! |( |' G9 }4 z$ B7 H
举个例子:
: H4 U0 p+ x: P/ U8 _7 _1 g- v& S9 ]4 ^9 M7 T! `2 O% z% ]' `
- /* 释放从DTCM申请的280字节空间 */
# h5 L8 x# \7 V& w5 v - osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
4 Y' ~5 ~+ V V$ g' Z3 c0 z' S+ z - DTCMUsed = MemHeadPtr(AppMallocDTCM);
8 M' a- U' Y1 N2 \" W8 L - printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n", DTCMUsed->used);
% Z$ P) n" `2 ]6 e6 a1 K R% ]
/ ^) D( g5 j6 ]1 i+ O% d- /* 释放从AXI SRAM申请的160字节空间 */
( l! I- ?$ v- n2 I! |% m - osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);! o$ F6 `$ h+ {5 L! e" U) ]
- AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
/ K8 J! P8 z: @ - printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n", AXISRAMUsed->used);
复制代码
1 X. R/ W+ [+ C: @' p" R, w27.3.2 IAR上的动态内存用法7 s& j0 y, ]8 i
注:IAR使用这个动态内存管理,仅在定义时跟MDK略有不同,其它地方是一样的。# S5 t# \$ U: ^3 `- q: P
0 t+ w% D# M% p$ u8 w+ r 定义动态内存区 Y% L0 t( Q0 _! K
比如当前的主RAM用的DTCM,我们就可以直接定义一块大的数组作为动态内存空间:
( c) E- m- ]! r! x
* R% {/ q- O% R. h5 D/ g1 F- S) V* _- /* DTCM, 64KB */5 g! P1 i! H. N
- /* 用于获取当前使用的空间大小 */. H3 o5 C/ |* U6 i5 }6 l
- mem_head_t *DTCMUsed;
! N+ ]! j; Z9 ? - /* 定义为64位变量,首地址是8字节对齐 */
! X+ x: U. F; G/ }0 ]6 `! U - uint64_t AppMallocDTCM[64*1024/8];
复制代码 ( c: }! B7 e, U8 ?0 l( f( x
如果要使用AXI SRAM作为动态内存空间,可以使用__attribute__((at( )))指定地址。6 a8 h* C3 L) Y& B$ k
7 p8 \9 ^8 r/ }" L% a
- /* D1域, AXI SRAM, 512KB */- ?. U& I3 s+ G+ k g* q' y: U, |6 u2 C: _
- /* 用于获取当前使用的空间大小 */2 V# E$ `- M! O- }
- mem_head_t *AXISRAMUsed;
% C7 F0 G7 }& V/ u - /* 指定下面数组的地址为0x24000000 */ 1 M7 ` z3 W$ s; d: n& r, M! [
- #pragma location = 0x24000000. v! ^5 O2 H3 s8 b0 |. }
- uint64_t AppMallocAXISRAM[512*1024/8];
复制代码 * \3 \6 t5 v- p7 G* F2 } w
初始化动态内存区
3 @( w0 g) I0 L e/ A+ _' \调用动态内存管理提供的函数osRtxMemoryInit即可做初始化:6 K! z4 l0 D$ [/ U
0 `$ N, v' c) F7 M: k) R) q/ ^5 y- osRtxMemoryInit(AppMallocDTCM, sizeof(AppMallocDTCM));
: j- g# U" h* @ Q - osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
复制代码 & f" H V& v0 B" r
申请动态内存/ o3 e P, G& E6 m7 Q
通过函数void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type)做动态内存申请。
# y* r0 r( a" o9 m% t' r
+ S& a* J4 K% H1 }1 h2 y第1个参数填写内存区首地址,比如申请的AppMallocDTCM,就填AppMallocDTCM即可。1 }' O& }/ F1 t. ^+ d: w/ K5 ~
! a% H5 u! K0 V$ W5 `% E+ l0 @
第2个参数填写申请的字节大小,单位字节。
4 v* m) H- i6 u- Y* w7 @/ y# b7 A, g5 n0 S
第3个参数固定填0即可。 }4 Q: {* C% J/ w2 p# {
" P; b$ e9 u. E% X返回值是所申请缓冲区的首地址,如果没有空间可用,将返回NULL,这点要特别注意!
; ?8 i, @' l2 E$ A
) \" K; M# n) c7 h8 W, j0 j+ a举个例子:
. J4 I& y& G& q, z1 T
0 l3 R7 z9 T6 M* @" j- uint32_t *DTCM_Addres0, *AXISRAM_Addres0;, J& Q" ]& P( @# i$ k0 r
. j( }0 m" e! h8 P. R" y- /* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
% m1 C' V" o* e9 C$ e% b, K - DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
: O% j* Q+ f- U+ v1 z* ~ - DTCMUsed = MemHeadPtr(AppMallocDTCM);
/ D& L0 o, {% J2 m+ @7 A: n - printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n",
! u; V; o8 H$ S6 w+ K) q/ @ - DTCMUsed->size, DTCMUsed->used);$ v0 `- {8 S& x4 B& ^: ?* \, O
- e( U" L! p0 ]7 M/ n9 l* b |( s- /* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */
! ]( c" N+ B% K0 b7 } - AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
) M( a/ H, v2 f - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);$ O. S. c0 X @- o. y& V
- printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
# }: I$ m# k+ L# n7 G - AXISRAMUsed->size, AXISRAMUsed->used);
复制代码 ; s$ Y0 y9 o3 w
申请了空间后,就可以直接使用了。另外注意红色字体部分,通过DTCMUsed->used和AXISRAMUsed->used可以获取当前使用的空间大小。
4 M7 ~- n$ B, ~) a2 E, X: e) Y( [* |
释放动态内存
% C4 r, G0 @: b' L/ T% b通过函数uint32_t osRtxMemoryFree (void *mem, void *block)做动态内存释放。$ ^1 N- H( D* V% [- t: u; z
: p: M/ c0 J* B! v3 ?
第1个参数填写内存区首地址,比如释放的AppMallocDTCM,就填AppMallocDTCM即可。+ G/ ]) w& ]2 m, [
3 f. Q6 y) N& J第2个参数填写申请内存时所获取的内存区首地址,这里用于释放。 Z% A, c$ P6 {+ x& F. _' u* g$ q
1 l9 W& G$ Y3 h# b返回值,返回1表示成功,返回0表示失败。
, f7 v& J4 Q3 f( P( W5 S4 R/ U5 H0 m; }: w/ l3 a+ }) w8 l
举个例子:
) T! f7 x A }: @6 |+ C0 `3 R( `( N5 }8 m8 A* A- Z# }& a+ w
- /* 释放从DTCM申请的280字节空间 */; O4 d/ ` }+ P* F
- osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);+ x2 l, P7 V+ j/ |7 N8 K; ?
- DTCMUsed = MemHeadPtr(AppMallocDTCM);
, t3 s8 {0 b0 t- A# k' N2 u' k - printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n", DTCMUsed->used);. f1 e6 k1 B# ]% q" J1 h( l2 v9 K
& C; i7 \4 E& D( S+ b6 A6 Y: T- /* 释放从AXI SRAM申请的160字节空间 */" P$ S8 G7 J, G0 _
- osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
3 y$ K& p" z1 v1 w - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);( R9 y8 L0 O6 J: F
- printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n", AXISRAMUsed->used)
复制代码 : l, h- P' @9 Z
27.4 实验例程说明(MDK)# H# C- m( b% J2 r1 z g
配套例子:
) C- j1 l F* d# @, uV7-006_TCM,SRAM等五块内存的动态内存分配实现" I- v- Z" ?1 n
) T8 z! R+ y% p) I- a6 q: P$ R实验目的:
9 d2 _8 g: E* e1 G& |学习TCM,SRAM等五块内存的动态内存分配实现。- y1 T9 O0 P6 _- C3 b" S9 K# T
2 o2 Q. D) H. u' o5 @. }- _% n2 p1 {" s+ r5 O+ L
实验内容
5 K# l' `( g% n0 I$ `* Q启动自动重装软件定时器0,每100ms翻转一次LED2。
- i# I8 M4 l; ~& u9 a: L- a% e8 d/ {; D# H! L
3 _9 U5 h7 K8 ~ `* q
实验操作:- D' @6 g9 M3 Q+ l0 J- z! ^2 p% n5 [
K1键按下,从DTCM依次申请280字节,64字节和6111字节。, T& }" Y1 `2 |( A* t; b
K1键松开,释放从DTCM申请的空间。7 o" O6 Z! D. i5 d7 X
K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
! a6 Q, n5 l0 sK2键松开,释放从AXI SRAM申请的空间。7 t" w, h! r! Z) B1 W2 S& i
K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
9 ^) P# @/ d( R, LK3键松开,释放从D2域SRAM申请的空间。
6 @( _( Q; q& G, @& {) l S: n9 f摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。
9 v4 o; k7 U$ P0 r6 c摇杆OK键松开,释放从D3域SRAM申请的空间。2 B; o5 x5 n# D+ Q2 Z: Z$ y
6 o' c" b6 q2 h, j) K
8 a0 Z' O1 K4 M4 P* k- y* v; A% Y2 |上电后串口打印的信息:
: l7 N. o1 H) X n3 U+ n5 H/ J
0 a) y S3 i( F" S1 z波特率 115200,数据位 8,奇偶校验位无,停止位 1$ Q$ h; {# A( R; M3 l; P& L0 ]
5 D7 p! q& `& v) [0 Q
* I+ T- R0 Q1 g/ H, N
7 @! n4 |- L; s; ]1 F程序设计:) N8 [2 R( l U7 ^2 M$ f- x
( I1 k8 G {% V8 K/ h
系统栈大小分配:
5 ?, a; n7 h$ x+ I6 N' `
* c# e, `3 w, ?3 Z+ M. T; y) O# G& e! k
9 Y$ H: Q0 Q% @! T/ v
RAM空间用的DTCM:2 ?0 J' `+ C! S* o; [* w
- b8 E2 J* |% ^4 ]. h9 L. L- `% }/ G$ r, E% @+ Q! D
( i m4 U$ E3 u. l
硬件外设初始化
3 x4 z4 p" i. t
9 r- u; t8 F! z! h, {! V8 A硬件外设的初始化是在 bsp.c 文件实现: S; A6 E4 V7 {7 [
3 Q, V( P( e$ X( ^, M# X# P- /*& h4 i9 d k$ W- E9 ^; O
- *********************************************************************************************************& _( A. a8 A: }- l Y
- * 函 数 名: bsp_Init) g1 W- y; c) a( s. u1 e- j6 n
- * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次, a! C/ S# ~. X! Q# v
- * 形 参:无6 i5 G: y [: P# n
- * 返 回 值: 无& }* d4 q- d. ]; x& x9 |) i. g. V7 C
- *********************************************************************************************************
4 C9 F8 Y3 d( [. k0 y - */+ m s/ ]+ k1 B! t$ U
- void bsp_Init(void) X- K. E& k$ i: H) T: y+ D
- {6 O2 ^1 N! y4 l
- /* 配置MPU */- B& d+ C0 x- g9 C5 E
- MPU_Config();
& A* o1 @8 ?7 o( f( @ -
& T" e7 b4 K% h) b% h* Y' [ X - /* 使能L1 Cache */, \! `& R+ t! o: x$ Z0 t+ x. |9 n
- CPU_CACHE_Enable();
9 Z( l! f1 C! w - 4 f& X4 A/ j! h0 l/ T
- /*
( C2 [+ D2 b8 Y - STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:) k" A, ~" U0 I) |( _, @/ }4 \* W
- - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。+ O s. O; U& W
- - 设置NVIV优先级分组为4。
/ t- w$ ?# |3 K: u* M - */
" m# B9 p4 C4 g" X$ E - HAL_Init();
6 B9 d9 J; J3 w( \6 Y6 K4 Q - - C0 J: v3 l# S8 }! b2 G
- /*
9 s6 {$ a, o o* Z$ y+ [ - 配置系统时钟到400MHz
J( q( R" Z* x1 {5 S0 C) m* k - - 切换使用HSE。
6 T. a6 b$ w; Q4 m% N - - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
! |- J& M$ O, z3 d. A& l - */0 \; I9 L0 {* O$ j
- SystemClock_Config();9 S7 d& O* _- Z1 }- f4 s
- & A8 ^+ w: c0 C. _! O
- /*
6 t* q# [( t6 b9 Z! g. X - Event Recorder:
2 W; d3 G2 b; [2 M* K - - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
g% F2 V) C5 {: W! m( I5 L; i - - 默认不开启,如果要使能此选项,务必看V7开发板用户手册第xx章0 X. j1 a( ^) m) F8 Y- d. ]
- */
6 n( M- M. @. C) j/ e; ]% ]/ |! [) a - #if Enable_EventRecorder == 1
0 t/ B- n3 `" Z* T! B0 b - /* 初始化EventRecorder并开启 */# C$ @/ v1 D" l F( b
- EventRecorderInitialize(EventRecordAll, 1U);
5 b! {6 j/ G6 J. u0 A. @& y8 S - EventRecorderStart();
; |" ]6 J( f7 R5 Z2 N - #endif
, Y; C* e5 i* l) l4 q3 z0 I# K -
7 Y( O* m1 [& H, J; o& u' F B! H+ g - bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */+ D2 t; b; o* {( a* y( Z/ u/ B
- bsp_InitTimer(); /* 初始化滴答定时器 */
6 s$ u8 _ o! ~6 N9 ? - bsp_InitUart(); /* 初始化串口 */
1 N5 V6 [& D c/ n - bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
* w( U" I, M4 b7 Q- e - bsp_InitLed(); /* 初始化LED */
3 r! k* G. W6 ~( {% K7 y - }
复制代码 7 S1 Q3 I: Y' ]6 O1 ?0 Q+ o
MPU配置和Cache配置:
5 e8 {: m# i* S3 I. x数据Cache和指令Cache都开启。
, _: G) G' u5 l- t8 y
2 Z5 T6 i3 F r/ @AXI SRAM的MPU属性:
) B0 v0 y, w8 o- c: B' o3 G' f+ v. ?+ {% E
Write back, Read allocate,Write allocate。) t: y% U6 O; Y! L+ R0 N! o
% @4 y) j, M8 C( X
FMC的扩展IO的MPU属性:8 |5 T9 ?/ F) Y* e; ?3 t/ d5 [
6 |% f$ b. _! T) W( r: x7 x& G必须Device或者Strongly Ordered。
* X2 u) G! F6 b% l) H, M* W' e7 y4 D. m f: l' @
D2 SRAM1,SRAM2和SRAM3的MPU属性:
; \7 W Z5 {8 b4 A6 u9 P8 J7 j/ P) t% _% W6 q( V
Write through, read allocate,no write allocate。
, W2 m' g8 c% J$ G7 B; t; ^$ O x, ~5 I, V3 W$ c
D3 SRAM4的MPU属性:3 e5 d1 ?* j. ^$ n( @
( c* ]8 U; P8 V+ t$ n
Write through, read allocate,no write allocate。
* e6 r7 J* ?" ]/ C# Q& p2 ~% }: D- \2 x8 X2 C) {8 Y6 G# x5 k( g) \
- /*
* p/ F- S0 s S4 I y - *********************************************************************************************************
3 Z: z7 E: |/ w) R# a! c6 r - * 函 数 名: MPU_Config
2 t; u% W: V R1 K) C - * 功能说明: 配置MPU% h- ^( U, l" `3 i2 U K: Q+ c( ?% r. o
- * 形 参: 无
1 e1 d G8 o( z* Q - * 返 回 值: 无. s; q, C- x) }. B2 U6 r6 g
- *********************************************************************************************************2 v2 b6 O4 y" a8 }* F0 i. r
- */
1 s0 U4 O& { O8 k8 n; K1 X$ v - static void MPU_Config( void ), i: @( H+ w- G2 y* N8 k
- {$ {) n" l* }, k! l7 A9 ]
- MPU_Region_InitTypeDef MPU_InitStruct;3 l w* P3 c+ [* O6 O" q1 d
- 3 E6 |7 Y8 ]% V" h/ M& R1 J
- /* 禁止 MPU */1 J5 @) Y% I2 G. `- }
- HAL_MPU_Disable();
& y: X; q. I3 s! \+ l - 6 U6 ~/ _ T: u
- /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
: ~" j/ \2 F& D' D- ?& Y9 I - MPU_InitStruct.Enable = MPU_REGION_ENABLE;; r8 ?2 e6 A- c# z9 Q. l; N' Q
- MPU_InitStruct.BaseAddress = 0x24000000;
8 _- Q" d% A. h' T. _7 j } - MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
* ?* y. @- y" y1 R; N% O - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;& W+ e, U X& M# U. U
- MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;) x9 h7 N0 T5 J% x3 M" a
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
4 b- S6 F2 I( P6 q# i - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
3 b( t8 h8 ~( D1 e" A: g+ ? - MPU_InitStruct.Number = MPU_REGION_NUMBER0;
( d6 }/ t$ K2 m - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
* n# K9 |' I& v1 |0 B, E! D - MPU_InitStruct.SubRegionDisable = 0x00;
0 Y& q6 c; h8 a h J - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;# x6 p# a+ P5 W0 L
- " L. ], {: O' ^$ [9 L1 ~7 |
- HAL_MPU_ConfigRegion(&MPU_InitStruct);1 p/ r' i% r+ m! [/ j; L- C
-
! A' Q' h- L& b1 o' T - 7 W. N" n9 j% ~7 h4 O" ?3 H
- /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
1 y; D/ u* L- Z/ s9 Q! P8 C! m5 j1 ^( I - MPU_InitStruct.Enable = MPU_REGION_ENABLE;6 }0 s' C! q2 _. ~! u: Y; n
- MPU_InitStruct.BaseAddress = 0x60000000;: ?: Y9 ~! |3 z. _! I' \, ]
- MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
; V; R. Q. w! U. [0 [7 m5 S - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;9 ~, o6 ?& s9 w# b" \! n) O
- MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;6 J6 O1 y# Z6 L c
- MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;2 @& I0 [: Z" H( C2 U8 z# j5 E8 O2 L
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
3 \" u8 E0 T1 m. g3 }, ~ - MPU_InitStruct.Number = MPU_REGION_NUMBER1;
9 w1 a. J; Z, r M5 W8 T1 B5 ?7 c - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
+ Q7 W- A7 j6 O4 b+ l Q - MPU_InitStruct.SubRegionDisable = 0x00;
7 \7 a' D4 @5 l6 J/ F( K - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
2 g5 f1 {0 Q8 I( Y) Q; s' m) Y -
( u6 F/ f. m. v$ q8 Q& r. C+ Y - HAL_MPU_ConfigRegion(&MPU_InitStruct);
6 ~' d' E+ ]) S& Z$ ~% `( [/ H -
2 s$ P# ^# t& o4 I+ ]% Y - /* 配置SRAM1的属性为Write through, read allocate,no write allocate */9 Z- ~: Y* X( F9 y( G6 Z9 b8 M! L
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;7 c2 g; J# H7 b) Y. G1 z
- MPU_InitStruct.BaseAddress = 0x30000000;; R3 d- G( o( ]$ ?( ?8 I: {% u" E. V
- MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
1 U7 o9 v8 q% }. i# T - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
0 s. i# d) X% `6 G8 r! V9 Q2 C - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;; I3 j X9 h; I9 M6 |9 P
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
$ E' H: Z/ N2 [, O - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;. }& U2 d7 w F- o1 o$ _) R
- MPU_InitStruct.Number = MPU_REGION_NUMBER2;5 `) k6 J/ Y8 G( U; P" U0 t1 H
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;% V1 { P/ |" ~; K/ M7 p- H
- MPU_InitStruct.SubRegionDisable = 0x00;, Q3 g! l3 `0 |* m! O$ i
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;. ]+ d s: }& ?5 f! C3 q
" I2 V' Y m: c( w. {. T$ g- HAL_MPU_ConfigRegion(&MPU_InitStruct);
& E9 D- C; |" e -
! C% \$ L, l" _ - /* 配置SRAM2的属性为Write through, read allocate,no write allocate */
, @3 f @# N1 E- ]# o - MPU_InitStruct.Enable = MPU_REGION_ENABLE;
3 p$ H, |$ O8 |% L9 S/ Q$ S - MPU_InitStruct.BaseAddress = 0x30020000;4 q5 V$ h/ @8 f" p q8 k! u( e! t
- MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB; $ h; [( G7 w5 W2 m1 B* i7 J
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
3 _# f. `) r2 g# d: E - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
3 N# C5 o$ k7 b |- E+ w - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;! U! ]( e. Z) b. z1 S
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
" o0 ]4 v/ U8 U4 ]& o# U - MPU_InitStruct.Number = MPU_REGION_NUMBER3;
|: g$ V) K" f7 T( q% L - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
% Z7 W6 r3 O9 z* o4 w - MPU_InitStruct.SubRegionDisable = 0x00;
+ x) {4 x1 z+ Q6 u* A; {! \ - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;" _3 W! `7 o: Q% r5 d* h! K6 U& \
. N. m/ ^( k# D* E. G% v: i- HAL_MPU_ConfigRegion(&MPU_InitStruct);
1 J: \5 Q. x* F
$ n1 t* {, H0 Q, m- , L! s, D& {. c& r
- /* 配置SRAM3的属性为Write through, read allocate,no write allocate */
1 E" a4 J) a7 B8 i) @7 p4 D" t - MPU_InitStruct.Enable = MPU_REGION_ENABLE;
+ Y: z) ^7 i7 g4 x, Z8 P9 y6 T3 [ - MPU_InitStruct.BaseAddress = 0x30040000;+ G9 l% R1 B+ X# v3 {. z2 s
- MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_32KB; " K% g) i y7 B1 u. \" A& R
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;; }# n" c4 Q. ?: c( a, a
- MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;+ k$ ^$ g9 O' a1 Q$ y! _
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;. V* Z2 K4 G/ S0 M/ {' ~% O; x* b
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;9 a8 F) I; m: E0 \; O+ h
- MPU_InitStruct.Number = MPU_REGION_NUMBER4;
9 M @ \# n6 _9 g$ H - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
6 M* C+ O5 S; ^4 i7 l9 W t% L0 K! ? - MPU_InitStruct.SubRegionDisable = 0x00;0 X& P1 w" O" T+ D% x- t# u8 }
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
( c2 _" v" w3 f - 1 | H- C. J/ x8 \; L8 y& U7 P) n* b
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
' e# a" S }6 o -
: P$ o6 N) {; J5 f" i m -
" z) Z. h0 t4 ?+ I - /* 配置SRAM4的属性为Write through, read allocate,no write allocate */
) X% N2 O$ @+ d - MPU_InitStruct.Enable = MPU_REGION_ENABLE;
+ ]% \6 U3 i8 X9 { - MPU_InitStruct.BaseAddress = 0x38000000;' \$ s& {$ C& ?7 V/ Z' K$ v
- MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB; ; X- Z* \2 y0 d( J" b6 b4 w
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;3 p5 O% g( P3 G" _0 Y
- MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
$ @# V( o: Y2 Y/ V) X - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
# ~$ a* x: B: j - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
V/ H& L9 r* m, o - MPU_InitStruct.Number = MPU_REGION_NUMBER5;
' }/ ?+ r4 a7 ~" U - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;7 V6 c3 L$ ^; n0 y
- MPU_InitStruct.SubRegionDisable = 0x00;
# P$ f) @& g' u. \" Z6 q5 J3 K6 ^ - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
9 P% h3 ^5 `7 q& x: V1 ~8 ]9 }
0 O* N- z: C9 o l- HAL_MPU_ConfigRegion(&MPU_InitStruct);
( }5 J! r& W7 w! t3 R - * Z* \3 Z+ W3 [* b. H8 l3 m- {* A
- /*使能 MPU */
/ k% @, P5 Y0 f) u5 G - HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
: Q @" h7 ]2 Z5 t- D - }0 U; J" E4 k$ y1 }
& m2 e6 r# q6 c$ X% X2 |- /*2 a, X7 y; p0 Q8 c* `0 v
- *********************************************************************************************************
$ w: B2 b" E( U - * 函 数 名: CPU_CACHE_Enable' w4 Z. Z% ~6 ^# o; L7 R
- * 功能说明: 使能L1 Cache
) ]! i# e4 ~0 A# G; K9 ?, Y - * 形 参: 无: U/ {' F/ t# H0 E% C. x! Z
- * 返 回 值: 无
3 Y) z( f- E( E8 E - *********************************************************************************************************4 F- @! v# t3 f0 U
- */9 H4 b9 |# S/ T X
- static void CPU_CACHE_Enable(void)
0 B' ?0 d$ X+ ^( ?# p2 x L! |( o - {
& p5 [) J) j- O4 j( s+ a: [7 h - /* 使能 I-Cache */
j6 j4 }: B- w4 F$ U) w - SCB_EnableICache();
+ K0 H0 ?! V k) _' z - ' y! d, }0 R( k7 s/ [
- /* 使能 D-Cache */
7 d' q8 N- a; k- |" E/ ^ - SCB_EnableDCache();& M' k5 h( s+ k6 p! H+ p
- }
复制代码 ! d' `5 }7 L3 z0 z8 r. ?
主功能:: L/ x- N- H9 e& s# n- G
/ C0 w% u7 x2 \! A' X主程序实现如下操作:
0 d9 z X! c$ y& [& Q1 @4 H* Y8 E! H( |" F; ^4 s! U5 }
启动自动重装软件定时器0,每100ms翻转一次LED2。
$ Q) g; w3 B' h2 h$ Z5 X K1键按下,从DTCM依次申请280字节,64字节和6111字节。( Q% ^, x- j, ~
K1键松开,释放从DTCM申请的空间。
3 R" X/ O: B/ d4 Z# H K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
/ z$ w3 g/ e u& a K2键松开,释放从AXI SRAM申请的空间。
3 F2 G5 T4 x/ T7 m8 y) g K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
. K( @5 ^. ~0 _/ K2 g' T F K3键松开,释放从D2域SRAM申请的空间。, \; h7 H y% W
摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。' I, |3 }& {/ L4 L
摇杆OK键松开,释放从D3域SRAM申请的空间。0 J' v D# V% L# W
- /*8 ^0 I. H3 R% F" d6 ]. s
- *********************************************************************************************************
[0 b, }- U8 L - * 函 数 名: main% B2 ^; |. Q! D4 N
- * 功能说明: c程序入口6 |3 U1 T5 q5 b; d& |( }7 f: b$ o
- * 形 参: 无/ m2 x* x! d/ X, i" j
- * 返 回 值: 错误代码(无需处理)7 c" ]8 m. r E! l. N0 k
- *********************************************************************************************************
+ z- r# O4 d& r K3 Z - */: S1 ?! n/ a* I4 _
- int main(void)
( x. l3 P9 o; x/ _0 J: r - {
# R, W$ t$ i4 C; n } - uint8_t ucKeyCode; /* 按键代码 */
+ A. G& L, G# u- F- h' e - uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;" U* ?4 _* C5 U3 J% m/ p
- uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;
" j2 A( g( _: l- \ - uint8_t *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2;$ X6 P. j/ m+ @/ l: F: n* v
- # D6 u( |5 V* |3 A- F/ s l! Y& f
- , o8 X, C3 U2 ~# @5 L
- bsp_Init(); /* 硬件初始化 */8 C6 |- v! I+ v4 {" m
-
1 J+ m" [3 Q6 H% J1 ~. R! f - /* 初始化动态内存空间 */
- a* P! S! L9 v3 W# k. ^7 [; p$ v - osRtxMemoryInit(AppMallocDTCM, sizeof(AppMallocDTCM));
6 o) f* @, T5 c% Z7 L1 ~% i# i8 P - osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));; `. j9 p5 M% L& y$ F8 [$ y, `$ y
- osRtxMemoryInit(AppMallocSRAM1, sizeof(AppMallocSRAM1));
( w5 T9 X \8 l0 W9 L8 c - osRtxMemoryInit(AppMallocSRAM4, sizeof(AppMallocSRAM4));
5 x0 y3 r$ F% M6 a2 h - 0 q) F7 I3 R( L+ J4 j2 h2 R4 k
- PrintfLogo(); /* 打印例程名称和版本等信息 */
. `1 i; Y7 `# _' F7 Q - PrintfHelp(); /* 打印操作提示 */6 ^- K' |+ X t0 Q( N
" P7 u4 ^9 I s- bsp_StartAutoTimer(0, 100); /* 启动1个100ms的自动重装的定时器 */1 f- O; `6 }) o
- , V" [) z- O! m/ h
; \5 `' t, s6 ^5 w" h( K$ I5 ?- /* 进入主程序循环体 */
5 v) s# ^2 k* ]2 R8 r0 n+ p - while (1)
0 E2 J* Y" n" s r/ X" @ - {
4 L, t( N6 p) f- Y0 v* \ - bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */% V- Y0 r) G5 T" k8 S% r* Z
- 8 S6 }1 k* `) c9 v
- /* 判断定时器超时时间 */1 e0 v9 s! Y% I9 {' i2 O
- if (bsp_CheckTimer(0))
2 q/ ^$ K0 Y: b7 [. O0 q9 A - {$ {1 w: G V% v" K# a
- /* 每隔100ms 进来一次 */
( K W1 S. A$ C- X3 P - bsp_LedToggle(2);
/ T6 g/ c, {" y Z3 y5 N+ _ - }
7 A' X5 A3 q6 ]& l& e - 9 h, Z7 C; f& I8 K/ Q+ H
- /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
; B. I, }1 M* N - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
" J7 c# ?+ d( h$ K: _ - if (ucKeyCode != KEY_NONE)6 D) U+ v* i* u+ P# V8 }
- {
: Q& C7 @% q. _3 k+ A U' m - switch (ucKeyCode)
z# d. |3 C; S - {, G# T) `' _5 n; O1 P* O/ W
- /* 从DTCM依次申请280字节,64字节和6111字节 */+ |% n% r. T/ l7 Z2 C0 z
- case KEY_DOWN_K1: ' ~& l$ J+ r4 b8 Q5 C. O/ P
- /* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
) _. I8 k% q: g0 u7 |. V9 p: w4 L! d$ } - printf("=========================================================\r\n");2 p+ c+ K) D1 e F" m5 @' h& L
- DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
8 W/ {6 U% a4 C; Q - DTCMUsed = MemHeadPtr(AppMallocDTCM);* l' g0 k, c' k* v- x" P9 r
- printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n",
3 ?- K& h$ H. v9 X M, \/ H - DTCMUsed->size, DTCMUsed->used);. n" j& V0 ~1 b4 @0 ~- K- U! I
- ) K0 L7 p1 [3 I. h+ r) B2 ?
- /* 从DTCM申请64字节空间,使用指针变量DTCM_Addres1操作这些空间时不要超过64字节大小 */
4 F9 ^8 ~7 h+ Q - DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, 64, 0);
% ` d! |4 ^" G7 R - DTCMUsed = MemHeadPtr(AppMallocDTCM);. o. X- H8 J" a* m* ^" @* v$ _4 n
- printf("DTCM总大小 = %d字节,申请大小 = 0064字节,当前共使用大小 = %d字节\r\n",
9 E2 y8 p4 J6 E - DTCMUsed->size, DTCMUsed->used);8 ?- a- }& }+ C
- 2 K0 j% l2 Z7 e9 M
- /* 从DTCM申请6111字节空间,使用指针变量DTCM_Addres2操作这些空间时不要超过6111字节大小 */. S4 _' L4 `! _! z
- DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, 6111, 0);
& j: Y: V6 [/ y" p2 H - DTCMUsed = MemHeadPtr(AppMallocDTCM);
# j& d% d3 e1 O U) J% s1 D - printf("DTCM总大小 = %d字节,申请大小 = 6111字节,当前共使用大小 = %d字节\r\n",
- W, q$ Y5 x, Z. k; P- Q - DTCMUsed->size, DTCMUsed->used);+ ~$ {, a" y/ _! }$ F% y# {+ `, s
- break;7 I3 r6 W5 d9 j8 E; Z9 Z( p9 r
- # e7 |- x I0 w0 u& U
- /* 释放从DTCM申请的空间 */
' Q4 U( |" U2 Z; A2 O, G5 p6 \ - case KEY_UP_K1: ; {7 s$ R9 }7 }1 {: w' N
- /* 释放从DTCM申请的280字节空间 */7 w) a/ w+ P) }, }, L8 d8 m
- osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
2 W5 h* m- g4 J - DTCMUsed = MemHeadPtr(AppMallocDTCM);" S: J* Z- a4 D3 C) Z; B: u
- printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n",
|" _ h; V; ~0 U8 _4 s3 } - DTCMUsed->used);2 j5 d( t( W) j4 t8 U4 Q) ]
-
! s0 ]) X' n+ M; r0 V9 \/ Z8 ?- V+ x - /* 释放从DTCM申请的64字节空间 */
9 l& @8 Z2 i- ^. i6 j" y) q! A - osRtxMemoryFree(AppMallocDTCM, DTCM_Addres1);
, w/ p: A8 f4 l& k9 J - DTCMUsed = MemHeadPtr(AppMallocDTCM);8 X$ w1 x$ h' e1 l% h4 [3 P
- printf("释放DTCM动态内存区申请的0064字节,当前共使用大小 = %d字节\r\n",( N" h* U( B/ R' R" J w' E
- DTCMUsed->used);
) D u) _# q' l0 I0 X F1 P - . \$ i7 J$ k" Z$ k( g/ n
- /* 释放从DTCM申请的6111字节空间 */
' K$ A: {; y: O* B* @$ a: X - osRtxMemoryFree(AppMallocDTCM, DTCM_Addres2);$ \1 H7 U+ h$ h! b' x( G9 ^
- DTCMUsed = MemHeadPtr(AppMallocDTCM);. v M2 j$ i& i- l
- printf("释放DTCM动态内存区申请的6111字节,当前共使用大小 = %d字节\r\n",6 q# e/ F2 F3 T. F
- DTCMUsed->used);
% ~1 h. G7 U3 V - break;
5 S! v- z$ y2 U! }# f2 c -
1 C( {5 Y) m% s9 M$ K: |4 J* h' i2 |7 F$ i - /* 从AXI SRAM依次申请160字节,32字节和2333字节 */. J$ ]9 C9 K: w: [
- case KEY_DOWN_K2:
: ^3 ^, ]6 H( x. N8 Z: X" |, K% j - /* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */
" Z# K6 w# ?& F% U1 h - printf("=========================================================\r\n"); ' ^6 i9 `' v) O3 M6 f
- AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
& A5 Z6 Z( @" z3 G - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
5 c( i; N3 d. _& t/ ]1 c - printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n", 0 y: ^5 D0 g- f( t, M
- AXISRAMUsed->size, AXISRAMUsed->used);
, F% g* f% t( Z9 ^ - . F) c/ c- [1 O- J
- /* 从AXI SRAM 申请32字节空间,使用指针变量AXISRAM_Addres1操作这些空间时不要超过32字节大小 */3 p, y8 W' }6 f; _ A3 L& C
- AXISRAM_Addres1 = osRtxMemoryAlloc(AppMallocAXISRAM, 32, 0);- k. S2 P2 T! f" k
- AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
g7 J- [1 w! x$ G; O: |3 Q - printf("AXI SRAM总大小 = %d字节,申请大小 = 0032字节,当前共使用大小 = %d字节\r\n", 2 i2 F* k+ `, C, \( U
- AXISRAMUsed->size, AXISRAMUsed->used);
. y [0 Z1 l6 G6 k! z5 v" S1 H -
8 h! d6 P# C1 [' I - /* 从AXI SRAM 申请2333字节空间,使用指针变量AXISRAM_Addres2操作这些空间时不要超过2333字节大小 */
! z: w( F5 ~. D3 A6 g3 v. s& ~; K - AXISRAM_Addres2 = osRtxMemoryAlloc(AppMallocAXISRAM, 2333, 0);
7 s: G' N3 j3 c - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);3 w( |- J, P6 Z( W+ Y& u4 V2 w
- printf("AXI SRAM总大小 = %d字节,申请大小 = 2333字节,当前共使用大小 = %d字节\r\n",
2 n0 ]! q: m% c' O/ Y6 k - AXISRAMUsed->size, AXISRAMUsed->used);' H0 Q# I. |$ e9 O6 ~5 Z
- break;% u( t; d7 c( s e: A; O
-
3 y F0 G( s2 f# | - /* 释放从AXI SRAM申请的空间 */2 c8 b+ S) T; Q% o9 t7 ?
- case KEY_UP_K2:
! `' F3 m' K8 T - /* 释放从AXI SRAM申请的160字节空间 */( f! _+ D; g1 u1 m; a. ~* o
- osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
; Y P7 D* v$ {/ N W. n - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);$ T% }3 Z( {* M/ f+ h
- printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n",
6 s# X1 d$ o) J0 `( L - AXISRAMUsed->used);
. A5 P! V4 D" K7 Y5 J -
" s, P* N: Y& j# Q# A' I - /* 释放从AXI SRAM申请的32字节空间 */
" _$ Q- r% W: w# ?8 Z - osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres1);+ ?% n* }9 j: W( V
- AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
1 T8 R9 L, n, v7 `1 B3 _1 W - printf("释放AXI SRAM动态内存区申请的0032字节,当前共使用大小 = %d字节\r\n",/ [+ K* c% k' y0 b& H, ]1 s! R% o
- AXISRAMUsed->used);
! n- C, c% P/ J2 J8 i - # S) H6 ^. E6 c6 F
- /* 释放从AXI SRAM申请的2333字节空间 */- d2 c" b* v9 R
- osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres2);
8 Q- q0 K1 H5 ?; u7 M, g7 l - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
: |: c1 L% K; _" t - printf("释放AXI SRAM动态内存区申请的2333字节,当前共使用大小 = %d字节\r\n",
, {8 V% ^2 M5 w) a3 y0 E - AXISRAMUsed->used);
) y2 D4 Y4 T- l) C. Q - break;* {4 u, f! A' `+ b9 h7 U: ~, d. ]
- 4 F. p$ S' P4 y9 r
- /* 从D2域SRAM依次申请200字节,96字节和4111字节 */
+ O* o( V3 F D/ k* L. L - case KEY_DOWN_K3: 5 X- J$ K2 h+ ~0 r ~# a$ e0 N S
- /* 从D2域的SRAM申请200字节空间,使用指针变量SRAM1_Addres0操作这些空间时不要超过200字节大小 */
# S- I& l" j4 u, c, O0 R1 N5 `- ^ - printf("=========================================================\r\n");
, Y/ `- m- q) T/ w6 V4 H - SRAM1_Addres0 = osRtxMemoryAlloc(AppMallocSRAM1, 200, 0);
, L5 ]% A# J& x7 ~8 P - SRAM1Used = MemHeadPtr(AppMallocSRAM1);0 ]+ x1 ^+ Q* |+ m3 Z* x! Y1 r, P
- printf("D2域SRAM总大小 = %d字节,申请大小 = 0200字节,当前共使用大小 = %d字节\r\n", 0 K5 C6 c: C0 [
- SRAM1Used->size, SRAM1Used->used);
6 h$ M5 s. @7 U2 a$ u8 t. z' k3 h - # I7 h! T. _9 e) M
- /* 从D2域的SRAM申请96字节空间,使用指针变量SRAM1_Addres1操作这些空间时不要超过96字节大小 */
6 s4 P3 N. |$ H/ }1 x' }8 q7 d9 ?2 R* k - SRAM1_Addres1 = osRtxMemoryAlloc(AppMallocSRAM1, 96, 0);
1 S# F% E3 _) ]1 v - SRAM1Used = MemHeadPtr(AppMallocSRAM1);
$ f+ A+ d* y; O$ o. V% n - printf("D2域SRAM总大小 = %d字节,申请大小 = 0096字节,当前共使用大小 = %d字节\r\n", + R* K( B( h. m2 V9 j( t% M% h4 U c
- SRAM1Used->size, SRAM1Used->used);
& n u5 o3 n K* I& b; x; m -
+ W; j) `! }" J( M( v4 j - /* 从D2域的SRAM申请4111字节空间,使用指针变量SRAM1_Addres2操作这些空间时不要超过4111字节大小 */+ q* G; B. t: X! L3 [
- SRAM1_Addres2 = osRtxMemoryAlloc(AppMallocSRAM1, 4111, 0);8 i! ^" m1 ]: j- F3 V
- SRAM1Used = MemHeadPtr(AppMallocSRAM1);; ^ J( e/ y( {/ s& c
- printf("D2域SRAM总大小 = %d字节,申请大小 = 4111字节,当前共使用大小 = %d字节\r\n",
& ^" p* H: P% q5 G1 b - SRAM1Used->size, SRAM1Used->used);
1 C4 u E, F% Q1 k - break;
{& S6 r% ^$ N& } -
$ l8 G# s" v. ?3 Z8 T - /* 释放从D2域SRAM申请的空间 */
7 U, u- x. ] v2 O" W - case KEY_UP_K3:
2 ^3 ~' R0 Z- Y2 y( l - /* 释放从D2域的SRAM申请的200字节空间 */! T7 ?# I6 R! ~" H
- osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres0);+ v3 u8 z+ C' `; l. T
- SRAM1Used = MemHeadPtr(AppMallocSRAM1);6 d `2 W* T% J, h) [- i
- printf("释放D2域SRAM动态内存区申请的0200字节,当前共使用大小 = %d字节\r\n",; \- r7 K4 Y# m" Q
- SRAM1Used->used);
8 O9 d7 D2 X; M; h7 l# b - 1 h G; _% a0 N
- /* 释放从D2域的SRAM申请的96字节空间 */
6 Z( F/ r% |0 v1 t! p - osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres1);1 v- [6 Y+ p7 v4 i, O
- SRAM1Used = MemHeadPtr(AppMallocSRAM1);
6 V5 K2 O7 m. `. q. }# F e5 ? a - printf("释放D2域SRAM动态内存区申请的0096字节,当前共使用大小 = %d字节\r\n",, H6 X8 O* E6 m
- SRAM1Used->used);4 u# e! F- p: N- d& {
- + s" D/ r0 L$ y5 q! Q) S
- /* 释放从D2域的SRAM申请的4111字节空间 */0 r5 A4 |' L8 U, K; @* p
- osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres2);
4 K( } Z# u( M7 ]& a2 S+ w' d - SRAM1Used = MemHeadPtr(AppMallocSRAM1);
* J0 h2 _7 k4 B - printf("释放D2域SRAM动态内存区申请的4111字节,当前共使用大小 = %d字节\r\n",
- ?$ v) t# L" j$ B" G! N1 I4 \ - SRAM1Used->used);
* q- B: E0 Q3 t - break;. R8 R! Q7 j, \1 d1 h2 N0 s% r" d
-
7 C! n! \1 P+ ?# }: p - /* 从D3域SRAM依次申请300字节,128字节和5111字节 */8 y+ U. h. F. U p
- case JOY_DOWN_OK: # }0 |( e1 S3 J& U- h. } H0 f
- /* 从D3域的SRAM申请300字节空间,使用指针变量SRAM4_Addres0操作这些空间时不要超过300字节大小 */
, i V3 Y0 X0 L W/ x - printf("=========================================================\r\n"); - R1 C( v3 f' f( c
- SRAM4_Addres0 = osRtxMemoryAlloc(AppMallocSRAM4, 300, 0);- M: U n D( h0 @7 c
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);
) z% |: p! o4 N6 R, n- ? - printf("D3域SRAM总大小 = %d字节,申请大小 = 0300字节,当前共使用大小 = %d字节\r\n",
6 a. D8 `% B8 q# Z0 A8 _9 O" ^ - SRAM4Used->size, SRAM4Used->used);
- U- @6 P- b: }6 M7 c - 2 z0 ^5 u- E+ D; a& L2 _
- /* 从D3域的SRAM申请96字节空间,使用指针变量SRAM4_Addres1操作这些空间时不要超过96字节大小 */
2 S" B& ?5 k8 P - SRAM4_Addres1 = osRtxMemoryAlloc(AppMallocSRAM4, 128, 0);: O& g6 ?6 F3 n- M* W# H
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);
8 m. J8 I' U, X; u - printf("D3域SRAM总大小 = %d字节,申请大小 = 0128字节,当前共使用大小 = %d字节\r\n",
* c3 f) c4 P f! M3 r; { - SRAM4Used->size, SRAM4Used->used);
+ }8 p: |* j" \! k/ K4 T -
: w6 h) o5 ^2 u* t' M ] - /* 从D3域的SRAM申请5111字节空间,使用指针变量SRAM4_Addres2操作这些空间时不要超过5111字节大小 */
8 W2 w0 w, t% |( k) i2 e - SRAM4_Addres2 = osRtxMemoryAlloc(AppMallocSRAM4, 5111, 0);( ` r8 F8 k4 v; c1 t! b. F2 A
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);
. A8 ^6 \) n: | ]! V: b @, v - printf("D3域SRAM总大小 = %d字节,申请大小 = 5111字节,当前共使用大小 = %d字节\r\n", 2 K) j& }0 h2 [, ^
- SRAM4Used->size, SRAM4Used->used);
0 E9 _! U9 l1 Z: ?) Y - break;
' h: |2 |$ h) T+ Y- N -
6 u# o2 b3 l. W! o0 H5 `' [ - /* 释放从D3域SRAM申请的空间 */& [7 d5 R) b+ L! {6 J# r
- case JOY_UP_OK: ' d% ^% a5 J0 f& o& ?
- /* 释放从D3域的SRAM申请的300字节空间 */
6 w+ q) w$ j* R- d2 d% B$ y - osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres0);4 A$ |$ M5 I6 T0 ]0 x
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);9 b0 C ~: @2 K9 ~" C( t
- printf("释放D3域SRAM动态内存区申请的0300字节,当前共使用大小 = %d字节\r\n", " L" j! S! g) }1 b
- SRAM4Used->used); o: q+ v3 Q+ }8 A4 w4 U; k
-
y1 ~% h% p j# D$ A - /* 释放从D3域的SRAM申请的128字节空间 */9 L+ F# D" \( v3 {
- osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres1);
5 b0 u, q; X# e* q9 p - SRAM4Used = MemHeadPtr(AppMallocSRAM4);
M. X( j7 D7 }$ ? - printf("释放D3域SRAM动态内存区申请的0128字节,当前共使用大小 = %d字节\r\n",
! x" v+ x: \0 {. G - SRAM4Used->used);' O3 m/ K5 L' J# o
- " A% y4 ~# Y5 d
- /* 释放从D3域的SRAM申请的5111字节空间 */
9 a7 d# {" f8 R. v; ^ - osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres2); [) ^! a) J3 _6 S9 c
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);: F1 L+ ]5 e- D+ W
- printf("释放D3域SRAM动态内存区申请的5111字节,当前共使用大小 = %d字节\r\n",$ ]2 e- B. B g7 `8 M3 z
- SRAM4Used->used);; I7 J# }* ]# m, z$ _4 \! W5 f7 h
- break;
1 t; r0 L' U, d! T4 V, l9 U8 @! E -
4 s9 q5 B6 q2 H( t- G; I) t- E j6 U! X - default:- P, B z P. ~4 K$ ^: _
- /* 其它的键值不处理 */
# i, I& U5 k# Q/ a% v. ^ - break;
1 V7 \% l7 p t$ ], r - }
, e7 x( }9 L3 H" k, T; z - }8 q) z! C8 L3 X6 r4 w
- }
% {3 f- Y! k2 L$ z# R/ M - }
复制代码 # s4 c- Q8 i, R) N" K" s
27.5 实验例程说明(IAR)
7 L! [+ |8 `/ d& E t配套例子:
& s$ w9 W0 A9 e; s% b- gV7-006_TCM,SRAM等五块内存的动态内存分配实现 R- M6 p8 a+ c$ t
+ H8 t% p/ K2 u* |# @+ d实验目的:
6 W$ s9 T* _! a1 l) h( q) o学习TCM,SRAM等五块内存的动态内存分配实现。/ M' P. j& }. g6 J
7 L$ N+ g$ X0 l" g) i
$ i% [0 s1 P: m8 A% O/ M9 K1 M
实验内容: Y) g; @% h! ?1 D" J
启动自动重装软件定时器0,每100ms翻转一次LED2。" u$ K4 F+ Y( A6 A
. K: L! ] f/ Q: `3 G
实验操作:: s! E: }- o' k _
K1键按下,从DTCM依次申请280字节,64字节和6111字节。
" E% R( h. p y1 a% m7 dK1键松开,释放从DTCM申请的空间。
& O* _+ o. ^2 ~K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
, Y0 D& Z2 O/ U& b1 A- RK2键松开,释放从AXI SRAM申请的空间。) }2 _2 c) e& z, I
K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。2 m& q7 t3 Z( R# W) x3 D2 L
K3键松开,释放从D2域SRAM申请的空间。3 s/ O1 T. n3 n8 L$ \/ h
摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。4 _$ P% X& ?) S' b+ I8 H- y
摇杆OK键松开,释放从D3域SRAM申请的空间。
5 S5 J1 \4 \) t# z
" s) G. i8 |6 P$ v- R* a! k上电后串口打印的信息:
* d E% }/ v4 y5 N I5 Y
6 R R: m! P2 y! ]: L& p波特率 115200,数据位 8,奇偶校验位无,停止位 1
: h( U- ~+ }% `% o3 Q1 R; s8 c0 f$ b$ r
0 k( z3 F3 x) M
) N: ?) y: @6 T! Y1 q
程序设计:* ?, X$ H' k m- {, i
) ~2 X: }/ W; R) _: J# Q
系统栈大小分配:
$ i- B" B2 V: ^5 m$ A) T4 Q! ]4 O7 X, ~$ U4 m# N3 T5 C( ^5 w" n$ j
j1 K0 P( A0 ~- W3 U: z1 b
- z- R9 G- ]8 ?* K' b RAM空间用的DTCM:7 Z5 O: b$ Y) ^) A+ ~
. F% g& J9 `) d1 _
+ g1 D# e) N v" y& P% y, x5 U# }/ B4 o
硬件外设初始化! B8 g4 D, ~( y F
( e# k+ U5 C, |5 V+ G0 b, @
硬件外设的初始化是在 bsp.c 文件实现:; X) H" z) X, e: f2 J$ L6 r
' F% f9 C6 M4 U
- /*: m$ V8 a+ Q& c' P3 r$ \
- *********************************************************************************************************
) K, ]6 `; N: w) l- U - * 函 数 名: bsp_Init
, k( v8 l P+ F- s$ ` - * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次; S3 q3 A! H! F2 g; }, U; B
- * 形 参:无
' R$ I7 X7 ^9 p - * 返 回 值: 无
/ p4 V X6 ~1 N( O - *********************************************************************************************************
# r4 y- n" L2 v# s/ y7 ]2 @( G - */
/ T; r3 {9 ~$ J - void bsp_Init(void)) g2 F! `5 W% Z* G
- {
1 _9 z% w1 S5 ~+ u - /* 配置MPU */2 \% | K# k0 ?' M7 `% i& p
- MPU_Config();
* q" c! Q( P+ V$ R; l - 7 f; r7 K9 j- {0 D* p6 V1 y
- /* 使能L1 Cache */; M4 [# T# I: ?+ @1 z* C6 f
- CPU_CACHE_Enable();" [. L- }5 Q1 P: }: o9 y, M$ u
: O4 k1 N V6 V6 b' c5 S. @- /*
( v; x0 a r; {# g - STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:' D" H4 J q1 L
- - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。' S" m. P3 O) N% j. O
- - 设置NVIV优先级分组为4。! r; W+ H! r1 u# N l1 \! K- P
- */
% H0 u% q" z& e( }' @5 \ - HAL_Init();
- A1 I3 d( t ]) d
# m, V# p) B% l) ?- /* 7 n: W0 _' H# N
- 配置系统时钟到400MHz
9 {: B" q: I( l4 {4 G - - 切换使用HSE。
3 k3 g8 t$ m& b8 } `2 H7 @ - - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
- {5 [" _/ d8 @2 b6 x7 R - */
2 s! k- |7 c: }/ Z0 A7 S' ` - SystemClock_Config();
# f0 |% K# O9 ^" ]) n
6 j8 x3 B+ {% N) C# g. W- /* 8 G# ]+ _" N9 k, m* o7 P7 q
- Event Recorder:1 r: b& S# s; X3 g9 q
- - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
( C& c; ]. L1 L. K - - 默认不开启,如果要使能此选项,务必看V7开发板用户手册第xx章
! Y/ \( O7 X7 |# v7 A" K) v - */
0 A, Q+ _9 n# f' o, B* W - #if Enable_EventRecorder == 1 $ i: R" N" i8 }
- /* 初始化EventRecorder并开启 */
C7 j. I! x1 A1 ^$ B! C5 Z - EventRecorderInitialize(EventRecordAll, 1U);* b) |3 j% v" F* \, q; `" t
- EventRecorderStart();* X! Q0 ]2 u1 J( e9 c# ^+ w8 m, r
- #endif4 d$ p2 R; l& Q# h: ]4 S
-
: v9 m) [- x' V f - bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
* P4 c+ w! Q' { - bsp_InitTimer(); /* 初始化滴答定时器 */
! N' Z; B- C' {% J: v - bsp_InitUart(); /* 初始化串口 */
( v* r( L3 Q0 ]7 ~8 d. i5 x1 X - bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
: v( I( w* |6 T# j# W; \, G# d - bsp_InitLed(); /* 初始化LED */
+ e( h. z$ q9 j$ ^ - }
复制代码
0 H2 ~( [) F6 j1 \& R/ R2 J MPU配置和Cache配置:
: j% x6 i9 e# i$ `3 C
9 K0 b1 {1 D; y, r/ |' T数据Cache和指令Cache都开启。- l" O/ \8 L3 s: o' D6 c' ]
9 a1 G; b) u7 ?AXI SRAM的MPU属性:
. A t! I' X2 e0 v, s+ j) }
9 ]: h F! L& p8 m" F& m+ lWrite back, Read allocate,Write allocate。
2 V3 W( \2 r! q1 i" n( R. g$ W! C D9 l( m/ N2 X0 i" H
FMC的扩展IO的MPU属性:
$ ]- {1 h( B4 Q
6 z+ z6 E- i; m必须Device或者Strongly Ordered。
% S( p& Y* q7 V; g' g9 l# z' R
2 x2 u: P' B7 m' b' iD2 SRAM1,SRAM2和SRAM3的MPU属性:
2 E& u j- w, ^0 _ t. x8 {, q- n! u! L1 z3 s) @% x
Write through, read allocate,no write allocate。% J9 ]; u* w1 H3 F
/ |/ i, G. y0 xD3 SRAM4的MPU属性:
3 O* d+ M- q, f1 e2 |" J7 b! x4 Z5 D+ A& d6 @ I2 E( H9 t
Write through, read allocate,no write allocate。
3 K1 R$ ^' w, y( ?9 o/ R) J- I
- /* m% p6 R0 y6 v) _, M
- *********************************************************************************************************
0 y* [+ {) W' V - * 函 数 名: MPU_Config
4 a4 M0 V+ T/ @ C& U# t3 e - * 功能说明: 配置MPU
- j2 O0 V" T/ V9 n7 f - * 形 参: 无
) w! \+ G# v# g) H0 D - * 返 回 值: 无% m, y$ l o! a" J5 Z$ d0 `
- *********************************************************************************************************
9 t) r, T% e: Y% M - */2 L( {0 v+ `9 ~3 V
- static void MPU_Config( void )) f( }6 a2 t" K( N- V
- {- n1 {9 @7 ]* F- s6 Y
- MPU_Region_InitTypeDef MPU_InitStruct;4 {4 `8 j0 h5 R5 r: H5 G+ l
, b5 |% B, i# l" c- /* 禁止 MPU */. B, u& ]' w9 A
- HAL_MPU_Disable();
6 e. }0 R! y/ h& P* P
* v: C3 b4 p! d3 n8 j- /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
; h) z, b" v# ^7 `; Y - MPU_InitStruct.Enable = MPU_REGION_ENABLE;
' J+ Z/ g L& W8 t. Y9 G - MPU_InitStruct.BaseAddress = 0x24000000;8 L# U& @4 K$ O6 N5 n. d; x0 ~* C
- MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;" n4 v- A; ?$ X) |
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;9 G( u( n% ^- T# e+ t
- MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;( _, w, n/ w. Q- f$ Q# }2 s
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;5 \+ Y" |" S+ s
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;6 ~# \& |: Z; L; J0 e7 F
- MPU_InitStruct.Number = MPU_REGION_NUMBER0;& `8 s4 ?+ u! W8 ~5 {3 g
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;0 n' Q9 E1 {4 V: C0 y, z6 O
- MPU_InitStruct.SubRegionDisable = 0x00; e0 c# Y' K! T/ ?5 M8 I' h
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;9 l9 K# A) l# f3 ~
- $ s1 `* \) [; m( f) ~6 @
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
! T: {0 f2 m: a4 a- {, W - * w4 V# V) p: e% X1 g# s1 Q0 o
-
+ }8 c& [: U& s8 y. n - /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */* y. [+ b# a9 I4 @) c) W5 B
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;" T W$ Y. _0 [3 h! w
- MPU_InitStruct.BaseAddress = 0x60000000;
5 t- t/ W" N; H J0 { - MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
7 ]2 m" K$ m5 _% I* h3 f - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
$ \' M6 j5 s) m, ^1 k. q - MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
2 ^# w) W( E) L. P/ f7 n - MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
. u% P) c2 W; L3 } - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
; N5 ~, T `2 U3 F6 w4 K - MPU_InitStruct.Number = MPU_REGION_NUMBER1;7 l' ` I1 J0 `; o: N/ C! _
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;* }8 u3 T/ w; a* h/ \
- MPU_InitStruct.SubRegionDisable = 0x00;
- G8 z; w9 h9 U+ f - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
- J2 i$ G% S: v1 @* [9 u$ G; K3 d - # `( t7 Y0 D9 T
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
4 F0 B4 }* T* M. X& K: | - ' d# P4 g* \; a# p8 ~7 E2 \, g
- /* 配置SRAM1的属性为Write through, read allocate,no write allocate */! O% r( B$ D& O4 Y
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;. U$ J" s* g. t! f
- MPU_InitStruct.BaseAddress = 0x30000000;
. n& u- W/ R$ k+ u - MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB; 3 B+ J: r8 V4 Q. j' G
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
0 b+ _ T F, T0 G - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;( l, r) W4 x6 t: q. M- J1 I' W
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
! v5 C4 |# N2 O& Z' Y d H - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
5 t* H8 u! Q& q& B - MPU_InitStruct.Number = MPU_REGION_NUMBER2;
9 K/ L& r4 ]1 l" Z$ O. o - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;8 }9 E' X. d8 R
- MPU_InitStruct.SubRegionDisable = 0x00;7 R5 Z( W* C, h
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;# }0 n+ I* _ Q# d6 f( ]! t
; [# y4 W( q/ v" S- HAL_MPU_ConfigRegion(&MPU_InitStruct);
) z9 Z } h. e/ E0 h - . E3 u% [; m/ E. W. I& q
- /* 配置SRAM2的属性为Write through, read allocate,no write allocate */
9 A0 @+ K- k0 w) | - MPU_InitStruct.Enable = MPU_REGION_ENABLE;
& Y; W% J5 {$ q' J# Z - MPU_InitStruct.BaseAddress = 0x30020000;
- } z: j; h9 u2 F1 E- j l - MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
% b u. r! S( w8 V! h - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
t* e4 W9 S& G3 @+ h# z$ @" H - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
P* a! @$ u' D" B* f p - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
9 o- u/ F9 }8 ^ c - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
+ M# {3 J% r- j5 ^6 B: P9 D - MPU_InitStruct.Number = MPU_REGION_NUMBER3;
- v6 _# V- x% k& `1 l - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;$ U& P* d S2 Y2 n3 Q
- MPU_InitStruct.SubRegionDisable = 0x00;
5 \' W1 R4 Q7 I. h8 X - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
' E- h$ a( l7 @6 U' X7 Y6 Y
" F/ U. Q2 K0 _6 A' b! c: d( h2 j- HAL_MPU_ConfigRegion(&MPU_InitStruct);3 F. f* {8 E- k0 b! E: C
- $ o$ e% e/ N1 I+ }; q( ?( M, `3 |
- ; ~2 r3 x" }, u- B* R. D) a0 W6 c
- /* 配置SRAM3的属性为Write through, read allocate,no write allocate */) Q5 k4 Q6 x4 Z3 z, \3 Y
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;) e0 t, |% z6 [: Z
- MPU_InitStruct.BaseAddress = 0x30040000;
" h) }5 L! i! g7 y8 X$ g - MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_32KB;
/ s: C6 H- W" o7 W8 I - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;1 y7 J% Q" q. H
- MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;' _8 Q) A$ g( L" }& G% S B: e* T, u
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;$ w6 Z8 b1 p, n g( w3 J" p# T
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;" u4 @: }/ d; c( i& ~1 q# `- W3 [3 t6 h
- MPU_InitStruct.Number = MPU_REGION_NUMBER4;4 B' F0 N8 B. l" p/ i1 U2 w# @
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;1 I) u/ S/ T3 w3 E( o! V. W% x8 B- t
- MPU_InitStruct.SubRegionDisable = 0x00;$ X$ v4 O5 s6 f' E0 C! r
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;2 P3 S: `( x' o% F7 a5 A( L* X# o
+ Y/ t* } e J( Z9 v9 C; t) z: G" C+ t; V2 F- HAL_MPU_ConfigRegion(&MPU_InitStruct);
, Y5 I1 |3 n& a ?* j% }! B - 8 ~' C! ]0 l, E% j1 W
- ( X4 [3 @& C. [' Y6 ~0 c3 v7 a
- /* 配置SRAM4的属性为Write through, read allocate,no write allocate */6 J( p. d7 H6 |
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;5 d1 z9 Z* j. i' k' y
- MPU_InitStruct.BaseAddress = 0x38000000;
3 K0 r$ ?% W& h6 B - MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB; : e+ w Z0 A. i. H4 {: A& h7 j; u: [
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
0 \/ i% y+ `' G. l - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
z- G% C7 q6 m" e6 Z - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
; X p' I9 B6 J& [5 F' x - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
. t: o- y, {; O* i5 d - MPU_InitStruct.Number = MPU_REGION_NUMBER5;
+ p o! {. E, G, D9 B - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;0 p" @% C8 |) x3 n# L
- MPU_InitStruct.SubRegionDisable = 0x00;% Y) Z& B c6 [9 e* L
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;6 E. n) P8 {9 v3 L
- ( D0 k6 Y y- t; }7 u$ i ^& }
- HAL_MPU_ConfigRegion(&MPU_InitStruct);5 r9 B# i0 L9 U p
- ( X0 }. B+ A9 P; p' p! F
- /*使能 MPU */: I' o0 v0 [) k: p
- HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);2 R1 M- _% i) T
- }
% m' i; z- S3 z7 R+ ]3 T5 P6 M l: z
9 _! n' {, k, y* R+ y- /*3 G9 A& Q% Q0 E3 D" n
- *********************************************************************************************************
4 r5 m. ]: }) g( n1 k) U, e - * 函 数 名: CPU_CACHE_Enable5 q& w6 t* g7 N5 O0 h
- * 功能说明: 使能L1 Cache# J# A6 G8 O$ U& ~+ A3 b, p8 k
- * 形 参: 无
$ `, I# s$ _/ a& Q. B" e - * 返 回 值: 无, V- ?8 Y9 o2 J3 A+ B
- *********************************************************************************************************9 v, X3 V0 w1 D. a) o) ^" z2 e
- */( L4 H' @, F+ \- A" Y/ d- O
- static void CPU_CACHE_Enable(void)+ N% e( X0 F3 ?& O& {
- {
2 {4 J( S3 R! U/ Z3 l - /* 使能 I-Cache */+ [0 V; _5 U: \9 l k
- SCB_EnableICache();
! Q: s }# N, r# t- k3 S - 6 J2 A4 N+ X P8 u" M; S) @/ H
- /* 使能 D-Cache */
* X! Z+ \# P' `' R0 f* {/ X - SCB_EnableDCache();
# O; C; V1 b) | - }
复制代码 3 _* V) f/ y- P4 i* \& V
主功能:
4 F5 Y% z: [7 }; k8 @# A% H
0 ]9 f: S6 z5 ?% { K/ F主程序实现如下操作:% S2 D1 \4 ~4 f4 y6 r
8 n: ?% X& Z* N R
启动自动重装软件定时器0,每100ms翻转一次LED2。1 t' S0 N% W) Z* o, v \) ^
K1键按下,从DTCM依次申请280字节,64字节和6111字节。
6 \' G8 ~! H+ F0 k- s5 I K1键松开,释放从DTCM申请的空间。+ G% I- @" D& o
K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。- S' j$ J# p' c5 R6 ?) E6 I
K2键松开,释放从AXI SRAM申请的空间。
5 S: Z h! y) M8 U2 A K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
/ j2 R( B+ N& q3 _. K) G1 h K3键松开,释放从D2域SRAM申请的空间。) f2 v( p6 ]8 j& u+ u; h# n
摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。
9 o# ]$ V8 v& e7 H/ N 摇杆OK键松开,释放从D3域SRAM申请的空间。1 D% ~* [: W% _2 b! ]6 a1 v- h' s
- /*
5 E4 h# l6 [* M+ [ - *********************************************************************************************************0 {+ [5 K# H. G8 `# ?) z
- * 函 数 名: main
4 ?* V$ K/ s1 j+ y( l - * 功能说明: c程序入口
1 l3 p# {! @. Y, B7 Q& a" R8 [ - * 形 参: 无
7 g$ H, E6 J+ l6 e# S* V S - * 返 回 值: 错误代码(无需处理)
j5 A6 s& z: O& w - ********************************************************************************************************** ?- G! O6 K4 j9 s5 i, e1 G! t
- */+ H9 j; l2 E# [2 [ {2 t+ x1 P) E
- int main(void)
7 l- o4 b9 X% E ?" m5 i0 D/ R" | - {
5 j: y% S3 q+ E9 e+ {7 f - uint8_t ucKeyCode; /* 按键代码 */
* y6 D3 z' r% P c' I% i% S& w+ ` - uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;
+ z- R% ~% z; u# o/ { - uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;4 j, L4 f( `6 c6 x9 J" b
- uint8_t *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2;: N- j: g; y" b
- # S" k6 x( x1 ^9 `3 M; {
- : G: g# x7 ~- E( M* Y
- bsp_Init(); /* 硬件初始化 */
9 p* Z: I+ ?) Q/ |& [ - " h1 t+ K3 R$ J9 I- R
- /* 初始化动态内存空间 */
7 N& Z ?, a/ E' h( _ - osRtxMemoryInit(AppMallocDTCM, sizeof(AppMallocDTCM));; }) ^* o1 N. h/ d3 G1 p3 t4 ]
- osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
* a. o- M7 B' y9 r3 K - osRtxMemoryInit(AppMallocSRAM1, sizeof(AppMallocSRAM1));
' j3 W% m) \8 [3 @7 h. U( { - osRtxMemoryInit(AppMallocSRAM4, sizeof(AppMallocSRAM4));7 g |% [0 H& v' G, p ^" q2 [
-
, n) l! J* {0 R - PrintfLogo(); /* 打印例程名称和版本等信息 */
' U& @8 G' H. R( O4 D - PrintfHelp(); /* 打印操作提示 */% ^( v/ H6 y" X0 _% q* F
- * c% B) u, O- [, a, C- l4 |
- bsp_StartAutoTimer(0, 100); /* 启动1个100ms的自动重装的定时器 */
- K( s$ n% u6 ~ -
5 c8 Q( N- e g# \- h
: ~2 \/ V9 P9 {, Q7 o- /* 进入主程序循环体 *// t4 ^+ k- n+ v( R( q" c9 G8 p
- while (1)
0 a7 a, U- v/ U' P3 G! p - {+ W# A4 \9 n2 y* C! z5 s- q2 x, R
- bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */* v T1 B: c: k. b# f: i5 g
/ f$ b8 u1 Z, s6 u- /* 判断定时器超时时间 */
. T, s' S! ?! d1 n+ v - if (bsp_CheckTimer(0))
( O( b. m+ j4 e4 p: U - {$ j% Q1 k" S2 p8 d) k
- /* 每隔100ms 进来一次 */ ( h7 I% k! S' v- k2 S% x9 V) B% K
- bsp_LedToggle(2);
1 `$ K4 l4 [" S2 M% M1 J - }
3 @, N9 F* Q5 a1 ^; d( e - 3 K; x! K* U" N( U" o+ f
- /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */$ K( o. W* y3 q) G; \ X K! i
- ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */, ^1 C6 J" z( J2 c& Q: Q0 @+ e
- if (ucKeyCode != KEY_NONE)
6 X: a5 I( K2 H9 ?: s) ~ - {
% k5 X( `$ I) y3 ^+ ~ - switch (ucKeyCode)
7 m9 U' A0 d( L& z - {
$ w$ [% Y5 A. h% z: F8 g+ R) Q A - /* 从DTCM依次申请280字节,64字节和6111字节 */( z! [0 v. z1 d; E! f. u
- case KEY_DOWN_K1:
2 m ]# r4 {! F; a - /* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */: n% f% D, w, W5 u
- printf("=========================================================\r\n");1 W/ h) f+ _9 e; Z
- DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
* s' ^4 J2 T7 q D' j! T1 T9 X - DTCMUsed = MemHeadPtr(AppMallocDTCM);
\4 l( O9 Q) ? m - printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n", . U- I8 l9 Q0 B$ s1 \ c
- DTCMUsed->size, DTCMUsed->used);
6 @9 _$ D: j; Y# [1 {' Y" J -
+ L [$ @. x, p( l T - /* 从DTCM申请64字节空间,使用指针变量DTCM_Addres1操作这些空间时不要超过64字节大小 */
: Z$ D3 m* P7 P8 M5 X& i% Z - DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, 64, 0);& j0 l0 W6 {: y0 p
- DTCMUsed = MemHeadPtr(AppMallocDTCM);& B& P: ^$ o9 ]) X$ z: t
- printf("DTCM总大小 = %d字节,申请大小 = 0064字节,当前共使用大小 = %d字节\r\n", 3 v* e4 H$ ]1 h$ H5 E
- DTCMUsed->size, DTCMUsed->used);* L( ~! H9 b f- s' v3 U
- - ~/ b2 M4 L' d- n- {0 p
- /* 从DTCM申请6111字节空间,使用指针变量DTCM_Addres2操作这些空间时不要超过6111字节大小 */5 s5 w. d9 Z3 J- L- ]' [( I
- DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, 6111, 0);
! d( r, h r: u - DTCMUsed = MemHeadPtr(AppMallocDTCM);
$ x1 L7 ]. O; x( C0 k2 \; V - printf("DTCM总大小 = %d字节,申请大小 = 6111字节,当前共使用大小 = %d字节\r\n",
$ U6 R) j) L% h# \$ x# b - DTCMUsed->size, DTCMUsed->used);
( O1 e A. n Z: ^2 P& j - break;
E- F3 n1 Z4 p -
8 ?# ^3 b+ t" e" R8 G( W - /* 释放从DTCM申请的空间 */
' W7 T* M+ D' o. O6 }5 y - case KEY_UP_K1: # b6 G6 v) `& Z; x* |3 H* X
- /* 释放从DTCM申请的280字节空间 */" J) O. g [. b! C
- osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);. m4 F/ Y0 e0 r
- DTCMUsed = MemHeadPtr(AppMallocDTCM);' \: o) c* ?- G2 _# m/ S
- printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n",
1 w* m, }1 H* ^4 k, \1 _ - DTCMUsed->used);
; h4 E9 O' v' y" E- ~ -
7 ?7 @. i( t9 I c - /* 释放从DTCM申请的64字节空间 */5 _; e! f- D( N/ b6 x
- osRtxMemoryFree(AppMallocDTCM, DTCM_Addres1);
+ h3 ^! c' b& d* Q0 e# { - DTCMUsed = MemHeadPtr(AppMallocDTCM);- K/ v8 E) j* @
- printf("释放DTCM动态内存区申请的0064字节,当前共使用大小 = %d字节\r\n",
- |/ o& l& t- a1 _) { - DTCMUsed->used);
* ]5 s1 W/ ^5 c6 P) P6 q -
" X' u) L j: J! M - /* 释放从DTCM申请的6111字节空间 */
" H6 t( K# |2 v$ R. @ - osRtxMemoryFree(AppMallocDTCM, DTCM_Addres2);3 N( D) X6 k* l' p5 q( h( W
- DTCMUsed = MemHeadPtr(AppMallocDTCM);' _& p9 f- t' G _6 J
- printf("释放DTCM动态内存区申请的6111字节,当前共使用大小 = %d字节\r\n"," Y' U) }/ G* o# g6 ^& V) d
- DTCMUsed->used);0 Y- B2 W7 [ K7 C5 v5 W4 e
- break;! ~# s" R. F: \& Z% G
-
9 v$ n- S7 L# \5 b - /* 从AXI SRAM依次申请160字节,32字节和2333字节 */* J) N" x8 [( Z. k7 P1 [; k
- case KEY_DOWN_K2: % r2 W L; p4 Q3 g
- /* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */' s' q$ D/ }, g5 Q/ f* B* \
- printf("=========================================================\r\n");
' [ f: t5 G7 } - AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
" S* n3 z# ?3 h. ~, E - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
% ^0 Y+ w! a4 d& R2 Y - printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
, ^/ H, a6 E- ^$ @! l1 O - AXISRAMUsed->size, AXISRAMUsed->used);
; s2 E' ^2 t: \/ N - . e- p% U+ Z+ Y9 }
- /* 从AXI SRAM 申请32字节空间,使用指针变量AXISRAM_Addres1操作这些空间时不要超过32字节大小 */( @+ ]" T# \1 k. D$ ^
- AXISRAM_Addres1 = osRtxMemoryAlloc(AppMallocAXISRAM, 32, 0);. [ \5 a7 Y/ O$ o) }3 `
- AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
+ a0 R" x3 i+ x - printf("AXI SRAM总大小 = %d字节,申请大小 = 0032字节,当前共使用大小 = %d字节\r\n", 9 W$ ~7 E) f0 g* m) d
- AXISRAMUsed->size, AXISRAMUsed->used);
7 x; l1 |1 u7 i: \4 F! } -
5 s5 f0 q+ J1 { - /* 从AXI SRAM 申请2333字节空间,使用指针变量AXISRAM_Addres2操作这些空间时不要超过2333字节大小 */
2 }' I/ J3 [% n9 @ - AXISRAM_Addres2 = osRtxMemoryAlloc(AppMallocAXISRAM, 2333, 0);9 Y4 }' N( { v2 R5 C4 P# C9 c
- AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);* Z' l4 c; n, [
- printf("AXI SRAM总大小 = %d字节,申请大小 = 2333字节,当前共使用大小 = %d字节\r\n",
" ?* m0 r' r! I& E5 H9 K9 }: V - AXISRAMUsed->size, AXISRAMUsed->used);
+ J: W) u9 C" P- ~* i; h - break;
9 j+ l! s2 g' p! j -
4 K+ L" d# Q, Z - /* 释放从AXI SRAM申请的空间 */
* b* v; N- n" c1 N* |: M* x, Q( y - case KEY_UP_K2:
5 o" V4 k% W: q9 W( t8 ~ - /* 释放从AXI SRAM申请的160字节空间 *// R0 t( j+ P7 T+ M& Q) z8 {
- osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
3 A# G) l" b' E \7 V( G0 | - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);/ r6 N3 W S# w+ v9 a
- printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n",
# H) f& `7 L# J8 L" u- N q2 A7 f - AXISRAMUsed->used);/ Z: j' }8 J9 _ P- o
-
. s9 q% @6 k" Q3 A1 A- A - /* 释放从AXI SRAM申请的32字节空间 */4 s) W) v" z: ^, c6 A
- osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres1);
& {: \8 f! q6 Z" d/ S1 J - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);# X$ X# w, i# q% D
- printf("释放AXI SRAM动态内存区申请的0032字节,当前共使用大小 = %d字节\r\n",7 @+ u% L1 h' \3 F4 m
- AXISRAMUsed->used);! v. W! p! ^/ m! g
-
4 D9 G7 {7 o) Y6 H2 h# w% e - /* 释放从AXI SRAM申请的2333字节空间 */6 |$ M3 q# j" A& A! n/ Q/ R, q
- osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres2);
; c4 Y3 S$ d. U; G7 e - AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
9 |" y2 j# A/ s. C. R6 q - printf("释放AXI SRAM动态内存区申请的2333字节,当前共使用大小 = %d字节\r\n",
$ I7 \3 P N( Y! m - AXISRAMUsed->used);
9 Q4 J3 }( a$ ^0 Q4 a - break;
1 f% r' Y ^7 l; ?, o - % z: J9 I; H1 [8 y
- /* 从D2域SRAM依次申请200字节,96字节和4111字节 */
! G1 [$ u6 i# Z& w" g& \9 q - case KEY_DOWN_K3: ) X8 E" g4 P$ t, h3 G# s/ \3 s
- /* 从D2域的SRAM申请200字节空间,使用指针变量SRAM1_Addres0操作这些空间时不要超过200字节大小 */
/ s8 b' x Y8 N7 N2 E - printf("=========================================================\r\n");
" Y5 a! M8 x# F2 \* ? - SRAM1_Addres0 = osRtxMemoryAlloc(AppMallocSRAM1, 200, 0);
% m" V9 X& A$ a e - SRAM1Used = MemHeadPtr(AppMallocSRAM1);
% w% b% Y$ K! g" I% A - printf("D2域SRAM总大小 = %d字节,申请大小 = 0200字节,当前共使用大小 = %d字节\r\n",
7 c& u) M, r7 f - SRAM1Used->size, SRAM1Used->used);* Z' _; P& e7 V0 x$ \6 @: n) t t/ _
-
5 B/ o3 F0 e: j/ P6 M4 O! }, g - /* 从D2域的SRAM申请96字节空间,使用指针变量SRAM1_Addres1操作这些空间时不要超过96字节大小 */
! t+ {, q+ F3 w E - SRAM1_Addres1 = osRtxMemoryAlloc(AppMallocSRAM1, 96, 0);
) G2 O9 J0 B- n8 t8 [5 ~( A# c4 D - SRAM1Used = MemHeadPtr(AppMallocSRAM1);
; p8 Z' T9 T9 M* w - printf("D2域SRAM总大小 = %d字节,申请大小 = 0096字节,当前共使用大小 = %d字节\r\n", 9 ~- @: @8 i# L
- SRAM1Used->size, SRAM1Used->used);
" r/ w) [8 M7 ?2 o: U - % x+ R& i$ M/ w
- /* 从D2域的SRAM申请4111字节空间,使用指针变量SRAM1_Addres2操作这些空间时不要超过4111字节大小 */$ @+ ?; S) O7 l' o( [% Q, z
- SRAM1_Addres2 = osRtxMemoryAlloc(AppMallocSRAM1, 4111, 0);
7 p/ w; m x; k& u, f- q# ^ - SRAM1Used = MemHeadPtr(AppMallocSRAM1);
1 d3 S: y5 I6 H! B! _ - printf("D2域SRAM总大小 = %d字节,申请大小 = 4111字节,当前共使用大小 = %d字节\r\n", ! {2 e ~ M( \- b7 y0 [
- SRAM1Used->size, SRAM1Used->used);; F$ }" X6 @; @, H7 `; w; C' p) r) B
- break;( b( x5 a% ^, O& w
-
* i- _! f, w; I - /* 释放从D2域SRAM申请的空间 */
k! K. f# ^, x1 d - case KEY_UP_K3:
4 R' R b! u+ K" D - /* 释放从D2域的SRAM申请的200字节空间 */ P, S8 [' O8 z; y
- osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres0);4 u# T! ?& ^% f- X" e1 C
- SRAM1Used = MemHeadPtr(AppMallocSRAM1);
f% [! h$ ^; O. P( ^% x. m - printf("释放D2域SRAM动态内存区申请的0200字节,当前共使用大小 = %d字节\r\n",
3 O' r( S- Y5 v0 k/ ~ - SRAM1Used->used);
% S% e2 K9 V/ L \5 |- Q; m -
# [" P- m& d. c; @- ?' V% k - /* 释放从D2域的SRAM申请的96字节空间 */
& A3 C( H0 X7 L8 f& }. P0 k; c - osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres1);; M, I! P. [7 P! I0 k
- SRAM1Used = MemHeadPtr(AppMallocSRAM1);3 v) P# ?. H. e6 m3 g9 x# t( f
- printf("释放D2域SRAM动态内存区申请的0096字节,当前共使用大小 = %d字节\r\n",
& Y8 ~7 Y5 ]; J; N' r - SRAM1Used->used);
: e9 @# u& Z' r1 O. C6 H4 z! `4 d+ [. P -
" M' ^) h4 g4 ^/ A; ~9 _ - /* 释放从D2域的SRAM申请的4111字节空间 */
+ M9 Z) i% \2 Y2 v# X3 `9 ?3 a - osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres2);% t3 u# r+ _4 y
- SRAM1Used = MemHeadPtr(AppMallocSRAM1); f o- B7 i/ a- w
- printf("释放D2域SRAM动态内存区申请的4111字节,当前共使用大小 = %d字节\r\n",4 o2 m, s1 `: |. ^# q
- SRAM1Used->used);
4 B" ]5 ~ ]5 B. [ - break;! R! \6 Y# \7 J) n& M. G
-
% z: s' G- ?( h: b1 z6 F) m* F - /* 从D3域SRAM依次申请300字节,128字节和5111字节 */
- `1 f- r$ W% e' _ - case JOY_DOWN_OK:
$ F) R+ ^7 `! R$ s! W) b4 E - /* 从D3域的SRAM申请300字节空间,使用指针变量SRAM4_Addres0操作这些空间时不要超过300字节大小 */
E: o) n: q e- l7 ?( b/ x; k& N - printf("=========================================================\r\n"); : p) s8 f& D+ z6 i( A, Y* D
- SRAM4_Addres0 = osRtxMemoryAlloc(AppMallocSRAM4, 300, 0);
: W& X! w7 [7 ^' V: C; b8 s - SRAM4Used = MemHeadPtr(AppMallocSRAM4);4 C' r4 z X9 q! I1 `$ H) Y
- printf("D3域SRAM总大小 = %d字节,申请大小 = 0300字节,当前共使用大小 = %d字节\r\n", 3 U9 B0 Q) D3 x0 L1 S9 h7 D
- SRAM4Used->size, SRAM4Used->used);
* @! _ Q2 X9 L s -
" V6 b4 \! O- A' Y - /* 从D3域的SRAM申请96字节空间,使用指针变量SRAM4_Addres1操作这些空间时不要超过96字节大小 */6 w6 f9 W% w( U3 L Q! S
- SRAM4_Addres1 = osRtxMemoryAlloc(AppMallocSRAM4, 128, 0);4 M1 w; _# W a. S' i4 h+ J
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);
$ r9 @; e* ]3 B* Y - printf("D3域SRAM总大小 = %d字节,申请大小 = 0128字节,当前共使用大小 = %d字节\r\n", 8 ~$ ^/ f7 p' g k( e# \7 m: ]
- SRAM4Used->size, SRAM4Used->used);# }1 d+ m3 h4 ~9 p% q1 r- w
-
% A& A1 y) E+ C& S) ^ - /* 从D3域的SRAM申请5111字节空间,使用指针变量SRAM4_Addres2操作这些空间时不要超过5111字节大小 */
3 ^1 v( c" C, A+ P2 @ - SRAM4_Addres2 = osRtxMemoryAlloc(AppMallocSRAM4, 5111, 0);
- j3 S- ?+ P% @% s - SRAM4Used = MemHeadPtr(AppMallocSRAM4);0 e) R6 R. A0 ]% y
- printf("D3域SRAM总大小 = %d字节,申请大小 = 5111字节,当前共使用大小 = %d字节\r\n", ; g& |# P, H v9 b
- SRAM4Used->size, SRAM4Used->used);
) ^6 R5 H& b: ~" s: f% P' i( p/ z - break;+ Q; P5 D( }' r
- & q% | }9 X4 M6 P0 |
- /* 释放从D3域SRAM申请的空间 */3 s3 I Z8 n7 V! s5 G& g
- case JOY_UP_OK:
% E8 T5 S# m" {; D9 r - /* 释放从D3域的SRAM申请的300字节空间 */
0 H$ Y) _8 N. s( `: H2 }' j - osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres0);
6 f' }# h5 Z$ R1 ]9 o. X5 U1 R% D - SRAM4Used = MemHeadPtr(AppMallocSRAM4);- T; v! a E1 z \( l, J
- printf("释放D3域SRAM动态内存区申请的0300字节,当前共使用大小 = %d字节\r\n", 6 Z6 M2 _$ R, d) k4 C( y
- SRAM4Used->used);
* u0 y9 G3 t" U5 U9 R) M' q -
9 y7 f# X" T2 C4 d8 Y - /* 释放从D3域的SRAM申请的128字节空间 */
: t; P& T: O' O/ \* E* m& S4 l' f - osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres1);
6 p8 {% Y- x" J( s) J, _ - SRAM4Used = MemHeadPtr(AppMallocSRAM4);
; N6 g) @9 K9 F8 j) t9 e. p8 p - printf("释放D3域SRAM动态内存区申请的0128字节,当前共使用大小 = %d字节\r\n",
/ @/ b+ b$ ~' k( s- U# Z4 G" A - SRAM4Used->used);
3 `% f. `4 f, N+ z( I2 V6 T - ) R1 r0 U& t1 |. h! Q' t% D) g
- /* 释放从D3域的SRAM申请的5111字节空间 */
/ l9 v% y7 n6 K* _. E - osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres2);; e. E3 R( L+ e" V
- SRAM4Used = MemHeadPtr(AppMallocSRAM4);
, i. [6 ?! a0 N - printf("释放D3域SRAM动态内存区申请的5111字节,当前共使用大小 = %d字节\r\n",
; X# k1 W3 ^+ o" u - SRAM4Used->used);
; R- S! K7 M6 j3 F1 ]1 E - break;
# ^) W% N7 |; h1 f5 l5 C - - u$ a5 u# s* r) `( f: `. F
- default:
- F6 o1 P* ^" Z - /* 其它的键值不处理 */: v4 O J+ E0 n1 }- `% A! m
- break;
: r0 }5 y7 Y6 ^ - }5 ^+ O) ~# W% @
- }
* v: @, u! q: X# W* g - }. u7 Z& D% K- d' M$ N# m$ t. H2 T- S
- }
复制代码 4 b* Z( @# P* i8 M ?2 B( Y
27.6 总结
/ s3 r( C) w0 d2 u9 G( G本章节就为大家讲解这么多,还是比较有项目实用价值的,特别是MP3编解码,JPEG编解码,视频播放器,矢量字体等需要动态内存的场合。! |: K8 B* G; z- d( t
- A @- F3 C' ]6 n/ u6 n; q( q/ o& D+ H4 s9 [; U4 w0 {7 U
4 {& f" S% x2 [
|