
本代码基于无操作系统的STM32单片机开发,功能强大,可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。直接贴代码: memory.h: #ifndef __MEMORY_H__#define __MEMORY_H__9 V$ }$ A) g h1 {6 {$ {7 Y 5 A* _! S0 L6 l' j; X5 t #include "stdio.h"( s8 F1 a v. _2 u- ]. w #include "string.h"$ h- D, v5 \; k- Z& n u #include "includes.h" //用户使用7 `/ I$ @: B% B$ k typedef struct9 u2 o4 L1 P8 b s* N, Z; T% Z {' S; W5 f/ X5 i2 m void *addr; //申请到的内存的起始地址 uint32_t size; //申请到的内存的大小,按照块大小分配,大于等于申请大小4 {1 p" b# Y# i, G1 V; j+ j( n9 P uint16_t tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用 }DMEM; . J h6 ~' V5 g1 Q$ X3 g: C" g //若返回空,则申请失败 DMEM *DynMemGet(uint32_t size);# }3 p9 Q; Z2 W' @3 d( q( ] void DynMemPut(DMEM *pDmem); 7 y9 o2 V( k2 r; h) A #endif //__MEMORY_H__8 ?" }5 A* J! {# B : B. r5 G( [7 k) T, \: a memory.c: #include "memory.h"; n* k1 m2 ^/ H" l#define DMEM_BLOCK_SIZE 256 //内存块大小为128字节) F7 V' V2 P5 \4 j, p #define DMEM_BLOCK_NUM 20 //内存块个数为40个 #define DMEM_TOTAL_SIZE (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) //内存总大小 6 Y) T$ E, v) o+ x, u* d& @ typedef enum { DMEM_FREE = 0,! w! j. |+ W' x9 n! J, E6 A9 F DMEM_USED = 1,4 P$ t- q s& k }DMEM_USED_ITEM;! G0 p" |7 G, E K' f typedef struct0 W+ }$ X: H \- B, e# K6 C {& X$ z3 s i7 @: F+ ^' W; E3 C DMEM_USED_ITEM used; //使用状态 uint16_t blk_s; //起始块序号) ~' \/ V" i) e# ?. }6 H, b R uint16_t blk_num; //块个数 }DMEM_APPLY; ; j7 R. \0 ?, N. q: K- K5 a typedef struct. @5 Y: \! d) G$ ^6 } {" L0 k4 }- e3 ]5 C- `& B* C DMEM_USED_ITEM tb_blk[DMEM_BLOCK_NUM]; DMEM tb_user[DMEM_BLOCK_NUM]; //用户申请内存信息; W/ ^. B' N/ v: O# w& m! y$ | DMEM_APPLY tb_apply[DMEM_BLOCK_NUM]; //系统分配内存信息, T& j0 {% T8 O, K m uint16_t apply_num; //内存申请表占用数目1 _: J. [" a& O& \5 k5 t uint16_t blk_num; //内存块占用数目$ g7 d/ q* [# M) }( _ }DMEM_STATE;7 ?( @' |$ y1 v9 U1 |2 \- A * `. q, Y- d- i7 ?, J& s$ j4 ~8 g static uint8_t DMEMORY[DMEM_TOTAL_SIZE]; static DMEM_STATE DMEMS = {0}; * j! G/ S c5 }* [9 r) \! k& q7 k: w6 t DMEM *DynMemGet(uint32_t size) { uint16_t loop = 0;' J; G: z) {" g) n4 e' g uint16_t find = 0; uint16_t blk_num_want = 0;( l0 `8 x0 }/ O8 R; w* g5 _ DMEM * user = NULL;$ O; @5 [8 m3 V4 c4 t5 B- ?& @/ w DMEM_APPLY *apply = NULL; //申请内存大小不能为05 b6 ?/ ]) J+ T/ j% W' \" q0 U if(size == 0) { return NULL; }, m( w. N: v/ f' J4 {9 x //申请内存不可超过总内存大小 if(size > DMEM_TOTAL_SIZE) { return NULL; }5 q) c. ?* U# E //申请内存不可超过剩余内存大小# \) [) d& O+ F) C* k/ @& t# Q; m+ L if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE) { return NULL; }; [ z& l. K# i //申请表必须有空余 if(DMEMS.apply_num >= DMEM_BLOCK_NUM) { return NULL; } //计算所需连续块的个数$ B4 t' c) V R1 A% n2 Z" L6 W8 r- P4 | blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;/ i- E+ r4 p& s4 p( @/ L //寻找申请表 for(loop = 0; loop < DMEM_BLOCK_NUM; loop++) { if(DMEMS.tb_apply[loop].used == DMEM_FREE) { apply = &DMEMS.tb_apply[loop]; //申请表已找到 user = &DMEMS.tb_user[loop]; //用户表对应找到2 H* |* o- ^ D# | user->tb = loop; //申请表编号记录 user->size = blk_num_want * DMEM_BLOCK_SIZE; //分配大小计算 break;4 i& ^4 Z3 t# w. ^ } } //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验" o: B; }% ]# }0 D% ]. e if(loop == DMEM_BLOCK_NUM) { return NULL; } 0 M( _0 t& ~% m0 Z //寻找连续内存块 for(loop = 0; loop < DMEM_BLOCK_NUM; loop++) { if(DMEMS.tb_blk[loop] == DMEM_FREE)+ Z5 ^: o! a3 D; O* g% W {//找到第一个空闲内存块 for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++) {//找到下一个空闲内存块 if(DMEMS.tb_blk[loop + find] != DMEM_FREE)! B% G; K4 c* M! a4 X! `' A0 K {//发现已使用内存块# U6 [& T' H8 ^+ V& ~" |/ w5 _; X break;/ f+ t+ [ O1 d } }5 \9 v4 h- \- a, L, o% g if(find >= blk_num_want)4 W, q! A3 S4 Z8 f9 h {//寻找到的空闲内存块数目已经够用 user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE; //计算申请到的内存的地址 apply->blk_s = loop; //记录申请到的内存块首序号9 b; p1 t6 j$ @, v4 e( E apply->blk_num = blk_num_want; //记录申请到的内存块数目 for(find = 0 ; find < apply->blk_num; find++) { DMEMS.tb_blk[loop + find] = DMEM_USED; }7 C4 ]% A/ m. A4 ^# H apply->used = DMEM_USED; //标记申请表已使用! \8 A/ Y1 h, d! v! G) k' e% H' E DMEMS.apply_num += 1; DMEMS.blk_num += blk_num_want; 7 o4 E- [0 f" e5 V return user;( l$ _ P. B: r( |! Z( \5 g$ k } else1 ]. V+ U: }# m2 a {//寻找到的空闲内存块不够用,从下一个开始找 loop += find; } } }) i) ]- b, H3 M2 p9 H6 X7 P / A+ N! q) ?7 F# }, G" b9 } v //搜索整个内存块,未找到大小适合的空间% \5 i4 |" p9 a* y" K return NULL;) Z1 m" o- W1 o K1 }- V' N2 } } void DynMemPut(DMEM *user) { M: @" U$ p4 ?0 K ?& o8 v: F uint16_t loop = 0;3 b' Q6 f. u. h3 q //若参数为空,直接返回" C$ n+ W3 z# r& u6 G0 R: { if(NULL == user) { return; }& y; L9 H2 O4 {+ Q2 ~, s //释放内存空间& U; z* E m( [9 k$ c, X# ] 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++) { DMEMS.tb_blk[loop] = DMEM_FREE; DMEMS.blk_num -= 1;* h( _8 t8 y. T& y7 U* r* u# x }" |# k* A0 X& l2 v* W //释放申请表: C4 k5 x. N% k/ h9 z; Y4 Z DMEMS.tb_apply[user->tb].used = DMEM_FREE; DMEMS.apply_num -= 1; }) P' F; N d6 j# S |
内存管理 |
不错! |