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