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