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