目的:高效、快速的分配,并在适当的时候回收内存资源。最终就是实现malloc和free函数。(实现方法参考原子哥)
- N% S6 O' w% j: ]8 M2 z: z5 y( G8 i% J' H4 o
- #define CONFIG_SRAM_OUT_ENABLE 00 l n9 N! F8 Z& m2 l
2 [- S9 O& Q2 u9 N$ h- typedef enum
2 t% k7 B" e# V9 x4 M; [ - {
6 U4 L% ]9 i$ ~, b9 Q - SRAM_TYPE_IN, // 内部内存池
6 t+ w' ]( @- z k$ `5 i' d2 W - #if(CONFIG_SRAM_OUT_ENABLE == 1)
+ E0 C1 s6 H" X - SRAM_YPE_OUT, // 外部内存池(SDRAM)
* W0 a7 o+ [- y/ a/ |* A - #endif
: f4 y) z# E- @+ y& P - SRAM_TYPE_DTCM, // DTCM内存池(此部分SRAM仅仅CPU可以访问!!!)/ j6 L2 }) `! k& Z7 ]
- SRAM_TYPE_MAX, // 最多支持的SRAM块数.
6 j6 D2 A( z( D1 W2 q0 P - } sram_type_t;
9 i( W2 \6 D( V& h6 ~ - ! t. h4 r6 {1 m. d+ }: b
- // 内部SRAM
3 m" ~6 Y8 `! D) M7 ? - #define SRAM_IN_BLOCK_SIZE 64 // 内存块大小为64字节0 i' X* S, t6 s+ d& }+ f
- #define SRAM_IN_MAX_SIZE (160 * 1024) // 最大管理内存160K/ n% E6 B- D5 z& v; Q7 D0 u
- #define SRAM_IN_ALLOC_TABLE_SIZE (SRAM_IN_MAX_SIZE / SRAM_IN_BLOCK_SIZE)
# t, |3 K h G$ v! a - - b" X) U6 O5 g9 D1 k2 S
- #if(CONFIG_SRAM_OUT_ENABLE == 1)( O _/ H' `6 J0 C- A
- // 外部SDRAM里面
9 C/ ^- T6 o: {- p. H - #define SRAM_OUT_BLOCK_SIZE 64 // 内存块大小为64字节
6 N0 A8 W& I' q) A& ~ - #define SRAM_OUT_MAX_SIZE (100 *1024) // 最大管理内存100K: ~: u: e+ L" c: l& I8 I' w2 D* [
- #define SRAM_OUT_ALLOC_TABLE_SIZE (SRAM_OUT_MAX_SIZE / SRAM_OUT_BLOCK_SIZE)7 d) Q2 `+ z& k, x
- #endif
: z, T' S+ p; d( G; T0 ^
5 V; N! a0 a3 Y+ Z, i8 n, e$ I- // CCM,用于管理DTCM(特别注意,这部分SRAM,仅CPU可以访问!!)
; a; _7 ?2 I* M6 _/ O9 k5 l/ X - #define SRAM_DTCM_BLOCK_SIZE 64 //内存块大小为64字节
3 S, o3 l9 B; l. K. m4 P1 t - #define SRAM_DTCM_MAX_SIZE (100 *1024) //最大管理内存60K
$ c' B+ s9 ^# T - #define SRAM_DTCM_ALLOC_TABLE_SIZE (SRAM_DTCM_MAX_SIZE/SRAM_DTCM_BLOCK_SIZE)
3 p, w; A/ f) d, G8 G) { - //内存池(32字节对齐)2 D+ s" ^8 G; @7 J' B1 |* h
- __align(32) uint8_t sram_in_base[SRAM_IN_MAX_SIZE]; // 内部SRAM内存池+ X2 O {+ n0 }% l' T
- uint32_t sram_in_map_base[SRAM_IN_ALLOC_TABLE_SIZE];- r0 v* S9 c( ^, h V& b9 W& n
9 ?6 l3 ^- I) D- R" P- #if(CONFIG_SRAM_OUT_ENABLE == 1)0 |; x4 q! U5 J4 _
- __align(32) uint8_t sram_out_base[SRAM_OUT_MAX_SIZE] __attribute__((at(0xC01F4000))); // 外部SDRAM内存池$ r2 k3 x6 U( f3 Q k+ D: r
- uint32_t sram_out_map_base[SRAM_OUT_ALLOC_TABLE_SIZE] __attribute__((at(0xC01F4000 + SRAM_OUT_MAX_SIZE))); // 外部SRAM内存池MAP7 L) m% l/ X' S' [- F! ]& i
- #endif
; R! ] `* m4 U - ! r& X4 R$ e' c+ T
- __align(32) uint8_t sram_dtcm_base[SRAM_DTCM_MAX_SIZE] __attribute__((at(0x20000000))); // 内部DTCM内存池7 D, g( p1 V/ @) ^+ Z' @
- uint32_t sram_dtcm_map_base[SRAM_DTCM_ALLOC_TABLE_SIZE] __attribute__((at(0x20000000 + SRAM_DTCM_MAX_SIZE))); //内部DTCM内存池MAP
2 }7 P( ]. p( v/ J( k1 A( A - 2 j: A9 K5 `5 U6 u1 a% `
- static const uint32_t memtblsize[SRAM_TYPE_MAX] = {SRAM_IN_ALLOC_TABLE_SIZE,
, V3 l$ _) f: {) @6 O% R7 p( t - #if(CONFIG_SRAM_OUT_ENABLE == 1)
' `% Y3 X! N: S - SRAM_OUT_ALLOC_TABLE_SIZE,+ M5 I3 [/ ?' a5 {/ {& J
- #endif
5 T' ?& W/ [: p. `. N - SRAM_DTCM_ALLOC_TABLE_SIZE
0 t) `4 k e1 z$ u - }; //内存表大小 k7 \, g5 Y5 n2 i( E5 H5 ~2 p
- ; ^) y' {8 T, A. s
- static const uint32_t memblksize[SRAM_TYPE_MAX] = {SRAM_IN_BLOCK_SIZE,
) A) i, R) H9 F# i! G. O - #if(CONFIG_SRAM_OUT_ENABLE == 1)
% T( m, T6 V$ ^7 X) K* ? - SRAM_OUT_BLOCK_SIZE,) v3 R- f; D$ u9 G, n, |
- #endif
' j3 [: R6 A: ]0 K# Z - SRAM_DTCM_BLOCK_SIZE
* S- ~4 k1 T3 [7 N5 ~( x, K0 e - }; //内存分块大小
: {/ n* r! l; J+ V9 ^* u& {
8 Z7 L3 R6 z6 [- static const uint32_t memsize[SRAM_TYPE_MAX] = {SRAM_IN_MAX_SIZE,% S1 L% a& L/ ~) A; V3 Q
- #if(CONFIG_SRAM_OUT_ENABLE == 1): |1 m/ ~6 _1 T2 s( X! V# D& l
- SRAM_OUT_MAX_SIZE,8 s) l8 X% i5 z) c5 |
- #endif6 a H* ?' h% Q/ ]3 U0 K
- SRAM_DTCM_MAX_SIZE
2 v2 l5 w" O% m4 ^8 F4 v - }; //内存总大小
$ v+ {* Z6 {) _5 z: Q
: h% ~2 x: `6 Q4 N1 T: n% U, F' m, x- void mymem_init(uint8_t type);
' z) p' v- W: J* F4 \$ j - uint16_t mymem_perused(uint8_t type);
8 f( u& y) l$ P5 j6 v1 t
0 x8 X: l0 J$ R; q+ G- typedef struct
( e. s4 R, B7 n! P j# t" Z - {
3 ]# y$ U- Q8 n) P6 V - void (* init)(uint8_t );* D8 g% A& w' t
- uint16_t (* perused)(uint8_t); // 内存使用率# K/ E3 @8 _ s
- uint8_t *membase[SRAM_TYPE_MAX]; // 内存池 管理SRAMBANK个区域的内存" V" g W; ?3 e" K, b5 H+ {
- uint32_t *memmap[SRAM_TYPE_MAX]; // 内存管理状态表) x2 `' H0 q4 j
- uint8_t memrdy[SRAM_TYPE_MAX]; // 内存管理是否就绪
& R! i, p1 I8 i- ?5 d* v - } sram_dev_t;- F+ V3 d5 p- r
1 S4 q6 t9 P( o( [- //内存管理控制器
6 }9 n3 S6 @) Z F - static sram_dev_t sram_dev =
) g6 {3 r$ A) V7 o' S - {
. K, j( q, I0 ]# D7 m" P - mymem_init, // 内存初始化
" ?- t d, G) o( E0 u" G: L9 u, T - mymem_perused, // 内存使用率. H% K4 e0 M; U2 ^7 G$ l- B! u
- sram_in_base,
2 O7 `5 ]4 O( ] Z i2 n5 W- o/ e
8 e* H7 Q2 ~. _7 a d) F0 y& `- #if(CONFIG_SRAM_OUT_ENABLE == 1)
6 r7 J7 j- B; V1 y3 Q0 k - sram_out_base,
! U, x! T/ T% \% U# ~$ I0 n8 i - #endif
' G" o) d% x8 e: ? - sram_dtcm_base, // 内存池, x" X7 q6 j% r0 C4 T1 [
- sram_in_map_base,# w3 ], t2 V* X& b! E# C1 D
- #if(CONFIG_SRAM_OUT_ENABLE == 1)1 N$ r8 s" f# c/ @
- sram_out_map_base," C. V; p& X4 x1 W
- #endif
: _1 i# n7 W4 { z1 \& e( N# e - sram_dtcm_map_base,1 p1 M4 N/ J( ]; o
- 0,
% P- X: e \2 Z4 @# ^* `- ]- g9 O - #if(CONFIG_SRAM_OUT_ENABLE == 1)
' r7 t: A% l+ N' L; k) p - 0,* m( T/ B3 |; a- {, L/ _
- #endif$ d$ Y% C. z; f, V9 x! D
- 0,2 M% }/ l! V7 X( [) g9 N3 N
- };7 |( u+ {7 n5 c' s
- g* l- o! r' H- U3 g! z$ d% `% \( {- // 内存管理初始化! d, i- P: s$ k, R
- static void mymem_init(uint8_t memx)
& z; F' d8 f) L# _: v - {% l9 Q5 Y7 H9 Z( Z/ u
- memset(sram_dev.memmap[memx], 0, memtblsize[memx] * 4); // 内存状态表数据清零
" l4 i- W9 d* v6 X9 j- d; U5 g3 c - sram_dev.memrdy[memx] = 1; // 内存管理初始化OK/ N7 r: L7 z0 p8 G
- }
& d% h- s j6 |2 N. Q - ) n. E. E2 k D6 v
- // 获取内存使用率
+ d& Q1 v, _6 S, `3 J - // type:所属内存块5 z% l) {4 u; q, c- b5 O
- // 返回值:使用率(扩大了10倍,0~1000,代表0.0%~100.0%)( r7 y" k; ]+ a8 e3 M" j$ { j
- static uint16_t mymem_perused(uint8_t type)( O) U- k' C5 m r
- {+ P1 Z1 ~4 c, G0 [; {% |4 I0 c
- uint32_t used = 0;
5 U- m) m) a0 m* d. F3 b - uint32_t i;
+ ?! G' F. y3 D. v& L7 p9 Y - for(i = 0; i < memtblsize[type]; ++i), e4 G R6 h0 E3 V
- {6 `- R( `1 a! A( p: k7 ] K0 _
- if(sram_dev.memmap[type]<i>)</i>' q% t8 n' Q, m- n* l
- {
$ b* |! J; Q. a3 s - used++;- B2 U! L* o2 h6 d- s: j0 y9 [! |6 _* G
- }
8 H6 w0 L8 P$ X; J% Y# U1 q - }7 v& F8 f# b( c' P
- : ^$ m5 t: \% |
- return (used * 1000) / (memtblsize[type]);! }' V k% c8 ^ H4 ]8 s
- }
4 Z- R2 Y% m! P0 O0 U' ~# n# w
: } E, X; z$ b5 `0 e- // 内存分配(内部调用); k) V% _; W- l2 W: R/ l6 T$ }
- // type:所属内存块
5 k$ b5 y- Z" Y+ a% \0 \ - // size:要分配的内存大小(字节)
) H% q$ J" C0 Y- P" Q; p- H - // 返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
7 y5 @2 Z- |+ d1 [. V* F - static uint32_t mymem_malloc(uint8_t type, uint32_t size)
4 V1 g2 v* _- w - {4 \* l7 T' F; A0 f& V, w
- signed long offset = 0;
7 j. k& z: K0 u. l - uint32_t nmemb; // 需要的内存块数" N! j* P' [: y; r% k% W' |
- uint32_t cmemb = 0; // 连续空内存块数) u$ \' x. H9 f* I4 k
- uint32_t i;4 f' L1 w1 S# P5 s
# h7 D m' H. S% |/ [: L- if(!sram_dev.memrdy[type]) u% y. B& F0 b& H9 R; G% g! N I
- {
& P2 c! ~" q1 m2 w/ W1 w4 p1 C - sram_dev.init(type); // 未初始化,先执行初始化
% p0 I4 d* Q8 Q- m8 ~6 z, ~# c - }
e6 ^- U% s0 ~1 A0 |* p) G - if(size == 0)
/ L! {( W s6 X6 r& s' G4 h - {
1 F( ]0 u7 C$ t' y - return 0xFFFFFFFF; // 不需要分配
* j% }& b) S, H - }5 j, ?5 I; H; X/ o# j- k1 K3 ^7 n
- nmemb = size / memblksize[type]; // 获取需要分配的连续内存块数' _: F% Z- I7 ~/ ^$ R) {
- if(size % memblksize[type])# M3 y- J& q/ f$ M0 W: R
- {9 y- J* ]2 e# o0 q# C9 u" k
- nmemb++;1 X0 _2 J6 u T; I: P# Q
- }
8 V1 u5 w8 h! f) w' T - for(offset = memtblsize[type] - 1; offset >= 0; offset--) // 搜索整个内存控制区: q. Y; h! s* [- i- Y) _9 L
- {
3 n# E( B% L X% n, W - if(!sram_dev.memmap[type][offset])
. [1 ^) H# v; P4 \0 b; ], l7 \5 w! e - {, w& S, Z' \# f4 M/ _
- cmemb++; // 连续空内存块数增加
6 ?" C2 f# m/ H" m' [7 A - }: s1 V, q, Z% p, e
- else4 ]3 y' Q$ C' @* @/ W3 \ U
- {8 ^9 ^6 c4 y) L! X/ I* H
- cmemb = 0; // 连续内存块清零( E) t6 s' n2 G2 G3 `8 I' ^3 q
- }
5 f/ Q! Q% J& P: @. A - if(cmemb == nmemb) // 找到了连续nmemb个空内存块
6 O, w% O0 z/ O - {
. j1 U1 \8 D) j; l( k5 E. Q7 W - for(i = 0; i < nmemb; i++) // 标注内存块非空' L8 W% w, G9 S1 i
- {& W- B2 r+ |9 |: k3 k& H4 H
- sram_dev.memmap[type][offset + i] = nmemb;. V* e0 ~; l3 u0 D
- }
2 N0 h+ u" h+ x5 p$ p. T1 [- W - return (offset * memblksize[type]); // 返回偏移地址& x2 S; a% | o
- }* r. j/ ]& ]( r: S* d( j/ D0 f
- }+ u0 V& H# \- h# m( Q
- return 0xFFFFFFFF; // 未找到符合分配条件的内存块
o- c8 u# Y! r, W2 V$ r7 o - }4 w! z* v( F- G1 a4 z7 S
- . d- k; x6 _6 _$ a7 ]+ T2 [( Y
- // 释放内存(内部调用): |" l% g. y! A% ]
- // type:所属内存块
' |1 @! I3 q5 f- ? - // offset:内存地址偏移5 N: v7 V# J" N$ X+ t- Q8 ], r
- // 返回值:0,释放成功;1,释放失败;8 L% s3 A2 e( J- m' H
- static uint8_t mymem_free(uint8_t type, uint32_t offset); L2 ], s U) r3 I
- {
0 Z' ^2 t9 a5 q/ h) q - int i;
( k9 ?2 z3 c9 ~5 f; Y3 E - if(!sram_dev.memrdy[type])// 未初始化,先执行初始化
" P% y9 Y3 J5 |9 b3 L - {
0 G0 t, C; n3 d: `; }4 r - sram_dev.init(type);
- x% T! Y# Z+ B. u2 l$ k - return 1;// 未初始化) ~9 |3 I0 n; O. G1 }# a+ ?! p& |
- }
?! b ^8 Y, U, E0 X$ o/ U, A5 t - if(offset < memsize[type]) // 偏移在内存池内.* X \ E! m" j/ m5 p
- {
# j" g0 y1 W, i; w. m1 d2 i - int index = offset / memblksize[type]; // 偏移所在内存块号码% _" v5 r: B" @0 f5 q% ~
- int nmemb = sram_dev.memmap[type][index]; // 内存块数量
2 z4 a a2 Z; q r* r$ F - for(i = 0; i < nmemb; i++) // 内存块清零' Z6 y$ ^8 Q4 T# A, y, N. Z
- {
6 A0 m) g1 }: L - sram_dev.memmap[type][index + i] = 0;
9 t4 a0 D/ F; ^6 _ - }
6 L! W9 \1 P' V - return 0;
/ A% g& m7 y3 R5 p( A7 e r f: h - }
8 W/ ^0 G% F0 M1 M$ W: V/ g - else. h0 Z$ B. W! K, Y% @. w
- {& J+ \) v. \/ |3 j1 x
- return 2; // 偏移超区了.; b7 G1 P* s$ O) i
- }
5 I- x4 t9 l6 |9 B5 w- ]; m - }1 I9 Y0 B' @ K& S1 f
- # q% Q3 E- k& R* W* X
- void MemInit(uint8_t type)# B4 g6 {2 [, Y8 ]5 j, i
- {
# z" _3 T5 F9 k - memset(sram_dev.memmap[type], 0, memtblsize[type] * 4); // 内存状态表数据清零
% E5 {, f% }! ~- w" T& i - sram_dev.memrdy[type] = 1; // 内存管理初始化OK k. M% L9 q( R+ D9 S' V# k
- }
2 J% @! Y0 p& }9 [5 l
" D% [% e$ c( u& o# c- // 释放内存(外部调用)& B: V, g9 y0 b, g) o+ {- m
- // type:所属内存块" R9 r2 Z% K3 E8 U
- // ptr:内存首地址
6 o5 }3 o9 G. j( r! a3 B) h - void MemFree(uint8_t type, void *ptr)% y/ f$ I) ^4 Z5 Z: ^: x# L
- {9 _3 l/ I ?# H
- uint32_t offset;
- K( k+ f5 ^5 ]8 [* D$ Z - if(ptr == NULL)% _$ F3 a3 Y7 ^$ v W- i. z
- {; a+ a5 O% }/ t/ r
- return; // 地址为0.
$ ^( H T ?4 n( M* @" S; J- G5 z3 J - }+ K E8 o/ O A, \: {: ^
- offset = (uint32_t)ptr - (uint32_t)sram_dev.membase[type];. h6 E1 }% t9 f' Z: j7 q0 u/ i
- mymem_free(type, offset); // 释放内存* M2 r2 W8 `% e& O% l. Z( y
- }4 N% u. C9 f" t- _
- K; z: u9 x+ ]+ ^, n
- // 分配内存$ v/ V4 u0 f% \
- void *MemAlloc(uint8_t type, uint32_t size)
% C, D: g. F |* ?' U2 a8 `; M - {3 r4 i( V# ]1 j4 k
- uint32_t offset;, [8 N- i. Q: a9 \) X/ m, a. \; x
- offset = mymem_malloc(type, size);3 Q _; ^; a; W \! a1 w* }' X
- if(offset == 0XFFFFFFFF)
3 j% h1 }4 H3 K1 Z. u& ~0 J - {
6 S9 D4 k t9 C+ m6 X3 E - return NULL;) }% L" V9 v' k$ i# U
- }
% H$ D9 h1 t* D, c% { y - else
& G) I2 d! ^% A; ? - {+ ]- q1 X6 ?9 r# q6 y, {: i6 j
- return (void*)((uint32_t)sram_dev.membase[type] + offset);
, ^) D( G/ a# X: j: [ - }
7 J* ?; G; J# u5 [ - }
! J4 w) ~; a+ p) I, w: O
4 {# ^ H. Z5 x; y ]9 V- // 重新分配内存8 h& p1 O/ _% p$ C# E9 z
- void *MemRealloc(uint8_t type, void *ptr, uint32_t size)
1 A5 m( @ r& Z. v8 \3 l& F+ A - {. {% |1 u. f, q
- uint32_t offset;
) f8 {, B; _6 U9 |" X - offset = mymem_malloc(type, size);
) ?- ^# o ]$ n8 m - if(offset == 0xFFFFFFFF)
$ j* e+ i( {0 J - {
. W6 N- ?' y) K1 h, H+ e5 i7 x - return NULL;+ k, Z* \. {. i% M5 j6 Q n
- }
# s2 p+ E9 ^8 u; R/ q - else
2 L% l' ^$ W/ n3 x - {
$ L( b& ]" }; X D M - memcpy((void*)((uint32_t)sram_dev.membase[type] + offset), ptr, size); // 拷贝旧内存内容到新内存
! q& J8 C! j- X; v* C' F9 \' Q - MemFree(type, ptr); // 释放旧内存& t# j+ f# `( Z( I5 [" q
- return (void*)((uint32_t)sram_dev.membase[type] + offset); // 返回新内存首地址
4 i/ ^1 V4 f4 Q/ H - }5 w8 z. v+ f1 A3 Z
- }
7 _( f, J6 N0 \: D* ~( T" R - . X6 ` |; p$ @1 V
复制代码 / M8 e8 F+ q" P
|