本代码适用于无操作系统的STM32单片机开发,功能强大。 可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。 直接复制粘贴如下代码即可: memory.h: - #ifndef __MEMORY_H__
+ X2 \7 Z( A: L3 j1 a3 s9 | - #define __MEMORY_H__
) Y3 @' e1 b& y" ?$ C1 t - : M5 |8 ?( e; z! h B
- #include "stdio.h"$ {! g. O% Q8 w: N8 N
- #include "string.h"
* l$ ?! o9 M0 M% ]3 s0 l6 K - #include "includes.h"
8 }; Y7 E7 e* T3 \! r - //用户使用
& } w I/ U1 S - typedef struct
. k4 `. t f# M: u6 k- ?9 [ - {
) K/ O( G+ z! b# Z+ }, o! U - void *addr;//申请到的内存的起始地址& ]% M) _( L: I" [% K l
- uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小' ~- V0 u, d c2 Q
- uint16_t tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用! y" W1 i* X- \& H! w
- }DMEM;
# |8 a- ~, e, o! X8 r0 ]4 J -
9 z' N) @- ~* a. k& q# G - //若返回空,则申请失败
/ p9 ]9 P( _6 K4 v- m- | - DMEM *DynMemGet(uint32_t size);
F$ u) a. x; k j/ k: L - void DynMemPut(DMEM *pDmem);
2 M1 }4 H. y6 i+ D2 h# } -
5 k, G+ L8 v7 l' @# G* L8 a9 \ - #endif //__MEMORY_H__
复制代码. W e; P* I/ p9 R- Y8 }
memory.c: - #include "memory.h"
7 l5 C4 Y6 h. ^% | -
# M3 d& c0 c' {) r - #define DMEM_BLOCK_SIZE 256 //内存块大小为128字节
5 H& q* s* L5 I5 x - #define DMEM_BLOCK_NUM 20 //内存块个数为40个
& {! K% j: X3 i, v. z - #define DMEM_TOTAL_SIZE (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) //内存总大小2 I8 `0 C4 c Z7 }% C4 r
- 2 n0 f4 ^3 q, u
- typedef enum
; j* H7 Q1 u6 o' j" ~ - {' h! Q$ R; o/ L* Y3 C; Y
- DMEM_FREE = 0,
( T% Y) p) N- G1 d - DMEM_USED = 1,
2 L/ {4 m) Y+ d5 o - }DMEM_USED_ITEM;3 o0 O4 n% q. j; X& ~
- p6 J% ?$ T5 d. I' C
- typedef struct/ ~6 y0 {1 N; C/ N" Q% A, {" F, W
- {
% d( V* r' j7 g8 E2 t - DMEM_USED_ITEM used; //使用状态2 W; u* O- w) r( w3 T8 {
- uint16_t blk_s; //起始块序号
" t$ s9 Z9 O" p6 C - uint16_t blk_num; //块个数4 K k1 o/ w# z# h( A
- }DMEM_APPLY;
. v& |% L! V( c) U - 6 e9 k# O5 m- k9 r- j
- typedef struct7 L' _3 B+ {' W& a
- {0 E3 f* v; n" }6 z. e# W3 l# [: ?3 H: f
- DMEM_USED_ITEM tb_blk[DMEM_BLOCK_NUM];" d, M9 e/ e! u3 c/ x, T
- DMEM tb_user[DMEM_BLOCK_NUM]; //用户申请内存信息9 d9 D4 i/ r! [+ a* S! }" z
- DMEM_APPLY tb_apply[DMEM_BLOCK_NUM]; //系统分配内存信息9 w2 P: E, [# \
- uint16_t apply_num; //内存申请表占用数目& F/ v% [, S) h* `
- uint16_t blk_num; //内存块占用数目
/ N# A! ?+ C7 ~- ]/ v - }DMEM_STATE;
2 [. G& t& j6 x" A4 i. m5 l -
' L& z% q# O- P- R - static uint8_t DMEMORY[DMEM_TOTAL_SIZE];, `" R# b- G; A7 p9 S: c* q
- static DMEM_STATE DMEMS = {0};
. m8 D6 S' a* x
( K2 B; |( Y( |0 n% H: W- DMEM *DynMemGet(uint32_t size)
1 J. ^, E4 I: a+ g" z' ] - { b, C/ p: S7 T
- uint16_t loop = 0;% v0 d1 m/ h* r! s% P1 z
- uint16_t find = 0;/ K) u0 g( p" T9 f& i
- uint16_t blk_num_want = 0;
2 e; U/ H3 D( X5 B( D - DMEM * user = NULL;
% O5 D7 \. E/ G( O* `& O - DMEM_APPLY *apply = NULL; n; N: F4 T8 U3 p
-
$ l. w. d1 }& o- C/ A; o! E - //申请内存大小不能为0
7 {6 X' J" _! z* \$ V6 L0 w - if(size == 0) { return NULL; }
1 T6 `. l b. `+ I: ]/ m: E - //申请内存不可超过总内存大小
8 p" r( w5 C; X) i - if(size > DMEM_TOTAL_SIZE) { return NULL; }
, K# @( z2 H0 H+ {5 I - //申请内存不可超过剩余内存大小
$ L4 S8 T7 Q% ?- w$ K( l1 a - if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE) { return NULL; }
6 k: k% e+ s) _0 z! x$ v0 L - //申请表必须有空余
, y7 s8 z$ r5 h1 E! Q' A0 v - if(DMEMS.apply_num >= DMEM_BLOCK_NUM) { return NULL; }
$ | B5 j4 z' F6 i. M5 Y - . n$ C$ c7 u! h" R4 N2 P$ D
- //计算所需连续块的个数
( ^1 u# b; O+ G# D - blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
/ v3 t% Z$ H6 b3 p+ K& T2 a -
) p0 j b; i* c) u/ a& Y% b - //寻找申请表
9 |$ m# P$ ~7 `, L0 m - for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)8 A* ^9 i$ a- o% k6 l. x+ Q$ @
- {- [% C/ r' ]0 i0 H9 e
- if(DMEMS.tb_apply[loop].used == DMEM_FREE), A& p, W Z- S, J9 F0 y/ _
- {" ?9 s4 f5 R' U( n# e7 a* j
- apply = &DMEMS.tb_apply[loop]; //申请表已找到
) i3 V2 ?: a! O7 v' j: b2 x - user = &DMEMS.tb_user[loop]; //用户表对应找到
6 V1 a5 _5 D8 T9 b% @; a - user->tb = loop; //申请表编号记录
) Z/ e! X8 s* v - user->size = blk_num_want * DMEM_BLOCK_SIZE; //分配大小计算7 H9 u0 ~: I3 d2 x/ E1 m( t
- break;
, a; z; K9 U) M" a" b/ R - }; z4 K' Q$ n1 s b) ^
- }
j# m- e; L0 Q( C# t! J - 6 U y& _3 [% u' p
- //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验9 ~7 }3 J6 \! V" g3 S
- if(loop == DMEM_BLOCK_NUM) { return NULL; }# d) e3 @ D' w3 f
-
2 J. Q) Z& x( v* M v2 s - //寻找连续内存块
$ G5 f) Y% V3 |! g! A. ]0 R - for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
% T: ?( U! f2 X, M4 ? - {1 n: L6 x5 V5 @) g
- if(DMEMS.tb_blk[loop] == DMEM_FREE)) u( S z0 \* {2 P
- {//找到第一个空闲内存块5 ]9 i$ E/ [' c4 s. y
- for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)
7 d" u: i5 o9 J$ D+ V - {//找到下一个空闲内存块! D5 A" V1 q! K4 A
- if(DMEMS.tb_blk[loop + find] != DMEM_FREE)
: e- u, V3 T+ `( `! h7 Q) h - {//发现已使用内存块7 }8 P( K9 Z! P9 A) [
- break;
# ?6 Y3 [/ K6 U7 | - }
* j$ z. R7 c1 x. D* K" o$ F - }
. ^; o8 ?- ]; }0 A& D - if(find >= blk_num_want)6 J. g9 r b+ a% E: B( J0 Q
- {//寻找到的空闲内存块数目已经够用
% g4 g. Z3 e r" ^6 k) | - user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE; //计算申请到的内存的地址
, g, K1 Y2 |- M1 b5 E - apply->blk_s = loop; //记录申请到的内存块首序号: W5 d5 S8 b4 K8 ^% t4 A9 F
- apply->blk_num = blk_num_want; //记录申请到的内存块数目- _) k$ g( a9 }. c% A7 {: Y6 d
- for(find = 0 ; find < apply->blk_num; find++)
F6 L1 u- }- B, C I) w0 N - {) B E% g8 ` y
- DMEMS.tb_blk[loop + find] = DMEM_USED;
( d; H, A# l! S+ }! A - }- y% k- ^$ Q; v) L! G
- apply->used = DMEM_USED; //标记申请表已使用
5 ^5 R& n( N. { - DMEMS.apply_num += 1;- w" m n$ f1 a/ X
- DMEMS.blk_num += blk_num_want;
$ k8 T" k5 `$ u9 \8 m -
( m9 P% w, {/ W i - return user;) q# N( j) G3 }- r( R2 L- f" B
- }1 Y* _ \; P+ y# N0 \$ \4 v
- else
# W- R5 C. w% ^1 U1 i3 R - {//寻找到的空闲内存块不够用,从下一个开始找$ \9 t' d% g" t) k5 S/ i
- loop += find;
( e1 h1 Q- C) o8 P( i1 k - }
S ?& G$ G+ f% { - }7 X" J: `) R4 W* w: Q
- }
2 D. E/ o& e" m8 D -
: @; z; c. J2 j) D - //搜索整个内存块,未找到大小适合的空间2 U$ d! E" ] P4 I
- return NULL;
1 c# C$ @0 B& \' W7 a J - }) X( _/ r: `( ^( M: O
- 5 c- N" O) |7 ]! ~/ H4 c+ i
- void DynMemPut(DMEM *user)
3 X% b& C- W) ]1 e: c5 m7 ?/ j - {
: A5 n2 w5 S- ^5 O - uint16_t loop = 0;' I/ |- H5 @ S' ^. e q
- //若参数为空,直接返回
3 i! U. Z7 p3 e7 `) b/ k - if(NULL == user) { return; }: s, f6 M% @$ s
- 9 K4 `$ O" m0 B' d3 B* r* D: f
- //释放内存空间
* `* o- O( z/ l - 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++)
" l: h* u6 _8 ^0 z9 ]. Q/ b6 \2 G% A - {
8 b) w# c4 N/ v2 f3 S - DMEMS.tb_blk[loop] = DMEM_FREE;& \7 Q3 N* j4 K3 z* S
- DMEMS.blk_num -= 1;- P+ Y% i( w1 p0 ?
- }' ]' \! G, F& d! ?+ k6 R+ V
- //释放申请表( g) [# T9 c: f2 t3 t' v) X) U
- DMEMS.tb_apply[user->tb].used = DMEM_FREE;! \1 @, ?7 o! E, a
- DMEMS.apply_num -= 1;9 N; b( i) }5 l' g# T
- }
复制代码 ) q1 E" I; l$ K6 E$ l
|