本代码适用于无操作系统的STM32单片机开发,功能强大。 可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。 直接复制粘贴如下代码即可: memory.h: - #ifndef __MEMORY_H__
, [# {( [4 W' i% k' B - #define __MEMORY_H__) ?1 x+ L, M7 Z
-
5 G; ~/ M9 b2 c( g* ^6 z- x - #include "stdio.h"& R& t! X0 }6 b; L- s+ ?" b
- #include "string.h"
8 g D( y" y6 b& X - #include "includes.h"
8 X; X" e8 ]" f. S% y - //用户使用
w5 u, d: U5 x - typedef struct4 ^7 u! \: Z* K2 E- w& _7 I
- {
# K n; q! A% h( V" I' `% ? - void *addr;//申请到的内存的起始地址
! o8 |0 R+ w" _* r0 i. F3 A+ A - uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小
, e3 m( ^1 q9 i$ A l# c# O - uint16_t tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用# a1 E8 G6 y) B3 \" N
- }DMEM;& h) ~9 c- N P6 w. e
- # A: N! E! q- T1 n2 s
- //若返回空,则申请失败
! n& @) c6 p0 l( g$ H: k: U( h7 K - DMEM *DynMemGet(uint32_t size);
& I) ?7 ~6 H1 x: a2 I; D - void DynMemPut(DMEM *pDmem);) T* O+ i' N. Q9 [/ i! i
- " C' z5 U( K- D$ ^4 `
- #endif //__MEMORY_H__
复制代码, F6 d( z: @$ W
memory.c: - #include "memory.h"% }4 O( T6 I5 t+ p/ i. }0 a
-
, N" w9 [, r0 a* z) [ n - #define DMEM_BLOCK_SIZE 256 //内存块大小为128字节
$ W7 y2 u, ^5 U! _3 J - #define DMEM_BLOCK_NUM 20 //内存块个数为40个
/ Q9 }, F ?. @5 _3 M4 F - #define DMEM_TOTAL_SIZE (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) //内存总大小+ ^' K9 Y+ e% s4 P; k
- ; T9 k {3 }7 i' l8 n
- typedef enum
1 h+ F7 i. h! |# ^ - {' h: t x# _( G0 N
- DMEM_FREE = 0,
9 r! m% K* j6 C5 q - DMEM_USED = 1,' ~* d2 E- g: G0 g" H! v; L! I8 T
- }DMEM_USED_ITEM;/ y+ r4 U/ _1 k2 t9 u" J5 A0 s
-
9 y" k8 H: R' c - typedef struct
' W( F! C2 a t0 n! Z, H' I - {
/ j( H3 ]( W) k& o/ C+ e5 f% ] - DMEM_USED_ITEM used; //使用状态
4 j9 C f$ d4 D% E( h! A6 J+ x; c - uint16_t blk_s; //起始块序号
4 [' J1 d1 m6 ?1 k: S+ p$ H - uint16_t blk_num; //块个数5 T+ U/ t8 g4 i+ M% h
- }DMEM_APPLY;3 B3 E- r" x3 ]# L# e/ o: E
- . }# O' {* h9 s$ f2 M
- typedef struct
& @' J! j- A7 t: x T - {6 e: q" R" n4 {6 O q! Q
- DMEM_USED_ITEM tb_blk[DMEM_BLOCK_NUM];
6 s+ X% o; F* u& K/ g - DMEM tb_user[DMEM_BLOCK_NUM]; //用户申请内存信息8 Z+ D6 U3 ]) f) ? R
- DMEM_APPLY tb_apply[DMEM_BLOCK_NUM]; //系统分配内存信息
0 `- j+ _7 B+ x% E1 G - uint16_t apply_num; //内存申请表占用数目
/ C2 v6 L- C8 r+ L$ w - uint16_t blk_num; //内存块占用数目
. G; H0 u5 }$ ], n - }DMEM_STATE;
6 n6 H! F2 l" v; c -
1 y, i( O# d Q: h: C* }; b) a - static uint8_t DMEMORY[DMEM_TOTAL_SIZE];
4 B' m+ C6 C2 x% l& o' P1 |% Q - static DMEM_STATE DMEMS = {0};
% v2 l- x9 ^* J8 b/ F3 I0 O$ d7 u: \ - / W- N, f) |# k% B. w8 x
- DMEM *DynMemGet(uint32_t size)& N( X; n1 o0 _4 b0 e
- {0 [ ?% M% W* Y/ k
- uint16_t loop = 0;% V. T! |$ L9 V# A8 f
- uint16_t find = 0;0 `! d0 A1 Y4 C$ l4 p3 Y8 y' N
- uint16_t blk_num_want = 0;
# n' i5 ?; C, u1 m( B; u6 K2 P - DMEM * user = NULL;$ ^2 S# B: y8 s& J' f- l
- DMEM_APPLY *apply = NULL;
8 c7 V0 o! L; r, A7 d - 8 C- D; }" K) L/ R6 ^; k4 w
- //申请内存大小不能为0
3 ~1 u o* V9 s6 { - if(size == 0) { return NULL; }% V2 l4 m% }# c$ s N& O5 [; _
- //申请内存不可超过总内存大小, G/ E: J9 A3 ~7 w3 H3 S
- if(size > DMEM_TOTAL_SIZE) { return NULL; } ?, [& m2 }* }0 |2 Z) D7 r
- //申请内存不可超过剩余内存大小
0 b$ a/ a" y& x3 K2 B& z - if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE) { return NULL; }
0 ?8 O o6 o/ C( ?. W* \4 u3 Q [ - //申请表必须有空余) h* ?4 u0 C# f' P# {, h
- if(DMEMS.apply_num >= DMEM_BLOCK_NUM) { return NULL; }( L9 P- b9 G1 z) R* r7 @/ t
-
+ l5 H, ^% c) }5 O" r% E - //计算所需连续块的个数
; R/ p7 l' n0 R9 F - blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
* L3 H- M ~& V1 B# X k9 C Z -
9 p/ Z( @* p# s; s) ` - //寻找申请表. @3 w6 J9 E X' z
- for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
# e9 t$ E; X4 E7 I% b - {
, w2 N5 y% j( o- F/ b& c1 a; S* n - if(DMEMS.tb_apply[loop].used == DMEM_FREE)& U' A5 n2 e. J/ e% ~
- {
9 y# ], _) N6 p2 f - apply = &DMEMS.tb_apply[loop]; //申请表已找到( c" e6 V. K; a* h$ `5 O1 g+ d
- user = &DMEMS.tb_user[loop]; //用户表对应找到
, P- C( J, d# A" v6 H - user->tb = loop; //申请表编号记录4 \. ]- z7 P: v6 r/ o% d) `0 \
- user->size = blk_num_want * DMEM_BLOCK_SIZE; //分配大小计算7 x7 r' J, H: o2 b
- break;
5 H! V! E" Z0 a - }' q) Y2 x8 Q" Q
- }' r. V% X; ]5 g' p
- % @1 t# R; e! h7 u. B' @
- //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验 F) o- U- P! h0 P& e8 D
- if(loop == DMEM_BLOCK_NUM) { return NULL; }
6 f9 Y5 O' @, p/ n8 W - 0 T$ R$ n2 C) I: w4 T
- //寻找连续内存块6 C) s: E! W% e) j/ Q
- for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
7 t/ |+ n: s7 J( m, I3 i0 q' N, i4 X - {
4 E E5 R0 E W$ d. m1 u) N, s: C0 X - if(DMEMS.tb_blk[loop] == DMEM_FREE)
G; ^3 L( ]9 F2 c! ]) t' j - {//找到第一个空闲内存块
' o% S+ b& s2 n7 u# X" B- b: f - for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++); r% n0 y1 f) F6 `% o; N
- {//找到下一个空闲内存块5 V" o% ]% x6 ]; f
- if(DMEMS.tb_blk[loop + find] != DMEM_FREE)' {7 X/ S7 |2 `8 Z* R/ N
- {//发现已使用内存块
9 Q' P1 b! p. e9 p* D9 J: }2 d+ O - break;, k& v! s; K7 x _
- }
; C# i0 \: L# o& N: U6 F5 v1 w8 D - }
$ O6 b/ a8 Y7 W - if(find >= blk_num_want)
# o2 r5 N; r* A* R% p C' ^: s - {//寻找到的空闲内存块数目已经够用
4 v9 x5 x/ ], S* G' R7 U - user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE; //计算申请到的内存的地址8 T1 {. P2 o9 a7 d9 C
- apply->blk_s = loop; //记录申请到的内存块首序号' L! B4 u0 _5 W( B" m
- apply->blk_num = blk_num_want; //记录申请到的内存块数目1 X7 A% r# j) O9 S' {
- for(find = 0 ; find < apply->blk_num; find++)
. U6 G( S* o! `5 q1 E - {
# O- e" m3 l$ U& Q; c0 ~ - DMEMS.tb_blk[loop + find] = DMEM_USED;! {8 s% a5 @* T' k) ]3 h) N( @
- }" p8 Z. q, p1 c8 Z6 X+ x
- apply->used = DMEM_USED; //标记申请表已使用
# P/ t, q! J# `4 @$ d% ? - DMEMS.apply_num += 1;2 r1 \! v* q7 ?, _
- DMEMS.blk_num += blk_num_want;
) A4 l7 R7 o% ~: F, F; @ - 9 s' ?+ M2 n! U8 [ p
- return user;: g' o( S- m" B# \, j4 r
- }& A- u+ z' T }2 O
- else
( `: }0 d1 G% q6 L& r - {//寻找到的空闲内存块不够用,从下一个开始找2 y& A: E6 Z; }& L
- loop += find;& c E2 i) ?. K* v
- }
* T9 E3 y7 a" e1 A - }! W0 B3 k0 w& L! D1 P
- }+ d; z' c3 d! }+ [' U
-
1 |' L! H! [2 V( \ V+ o6 ~- Z* C - //搜索整个内存块,未找到大小适合的空间
+ b8 P4 r I- N7 z2 ?; Z - return NULL;# v$ h; p+ \# u
- }
$ y% Z8 ^' X0 k - * H" J* V& y1 L/ X* R
- void DynMemPut(DMEM *user)
- P4 t# P2 P7 H! ^+ P$ O( k - {# e$ j8 {, \% k' z! Q" _4 D# J
- uint16_t loop = 0;
1 x" H" A% \3 g. f7 u( Y - //若参数为空,直接返回3 K- e' J& W z: Z
- if(NULL == user) { return; }: F M4 A' K2 g
- 9 m) G* f @/ [* a* P
- //释放内存空间
2 W$ d3 C& Y2 y! @# N8 ^* Q+ S' s. v( \/ r - for(loop = DMEMS.tb_apply[user->tb].blk_s; loop < DMEMS.tb_apply[user->tb].blk_s + DMEMS.tb_apply[user->tb].blk_num; loop++)
$ ?' {7 L- x$ Q* x' r5 ^ - {' U* O% ?# P& w: ^. I& R# `
- DMEMS.tb_blk[loop] = DMEM_FREE;
" b9 a6 [8 _3 b( W" N - DMEMS.blk_num -= 1;' k$ D- e3 i5 _$ z1 [, ~! |# i h
- }8 f p, N; P- X1 T* o- O
- //释放申请表( z( E: c5 Y& S! B8 }
- DMEMS.tb_apply[user->tb].used = DMEM_FREE;
' W( a5 {4 t" i - DMEMS.apply_num -= 1;- _& X, u Z6 {* T$ n: v
- }
复制代码 9 | p; g2 P/ N
|