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