本代码适用于无操作系统的STM32单片机开发,功能强大。 可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。 直接复制粘贴如下代码即可: memory.h: - #ifndef __MEMORY_H__! ^3 k2 \4 ]" U( b# b0 x
- #define __MEMORY_H__1 B8 J7 Y" s, O9 C: r; _
- ' S' ?0 n1 i2 Y
- #include "stdio.h"
/ Y% q$ I5 [* z& j, k - #include "string.h"8 ^+ _) _2 ^, o- k& k4 Q
- #include "includes.h"
" z! \; j7 S% b# | - //用户使用
, R3 m' P- i) U - typedef struct0 x2 h n: ~4 U1 V7 @' }7 Y
- {
8 x5 \; |: L3 y6 X5 n9 T/ d, _ - void *addr;//申请到的内存的起始地址/ a: c- M6 K: c) K+ E) f
- uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小
: S% W8 i; [" {1 v& R - uint16_t tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用# T8 }* y; c3 h' `6 q
- }DMEM;
5 A- Y; k2 v4 M -
+ q3 b8 _% r- v0 b2 X - //若返回空,则申请失败; }5 n; Z5 A+ ?0 {5 h& K
- DMEM *DynMemGet(uint32_t size);& b/ T3 x$ T) q4 r
- void DynMemPut(DMEM *pDmem);
/ q# V. C5 B+ k% ]. H$ P. P - % l9 H1 g& K$ I" g/ c
- #endif //__MEMORY_H__
复制代码
% L5 B8 V$ Q& {& r: _
memory.c: - #include "memory.h"
, S5 e( P% m+ f& l+ x* e - , F) s8 |) e/ h
- #define DMEM_BLOCK_SIZE 256 //内存块大小为128字节% b, q0 o; h6 C2 [* T ?. B
- #define DMEM_BLOCK_NUM 20 //内存块个数为40个 q9 Z; x) X$ v9 K& H
- #define DMEM_TOTAL_SIZE (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) //内存总大小$ J& h3 { [- R" n
- , w9 z; Z# b5 S% E3 w# J" C
- typedef enum& N; Z2 p! w; q8 m' w1 S0 }9 H& l
- {
`. T) \3 [( ^- c8 U - DMEM_FREE = 0,
( g {' W& U7 H: X+ H p8 V - DMEM_USED = 1,
. ~8 Z- ^2 S. M2 m: {. g/ t( } - }DMEM_USED_ITEM;
: C- {0 h5 R5 g0 U- f, H% x2 | - 4 m% V) Q% T) e/ s B! F
- typedef struct- `$ x2 `/ l" w8 k
- {
& Q& u$ a- \4 R/ {- P: U - DMEM_USED_ITEM used; //使用状态- X* r9 g$ Q. v0 P, ?
- uint16_t blk_s; //起始块序号) c' X# U( f7 x \& Z
- uint16_t blk_num; //块个数
) r# [3 n% v& V" A) T$ k) V - }DMEM_APPLY;
7 s. a% R5 n, f6 P/ h9 r - % I" P3 A4 S- \
- typedef struct. ^7 i' Y) |5 F3 T( A3 L
- {
r& Q( X7 D( p8 b" {1 p/ Z - DMEM_USED_ITEM tb_blk[DMEM_BLOCK_NUM];
' Q! K, {1 j* w" Z - DMEM tb_user[DMEM_BLOCK_NUM]; //用户申请内存信息
2 ?8 o- k ?0 Q, ^& _; ?4 U" f - DMEM_APPLY tb_apply[DMEM_BLOCK_NUM]; //系统分配内存信息
. o1 S6 g% |$ l2 i; {2 c: c - uint16_t apply_num; //内存申请表占用数目: F: m3 z: i' p8 V7 x' N `- r
- uint16_t blk_num; //内存块占用数目
5 L! j$ e! y/ w3 w8 \! X4 } - }DMEM_STATE;; m' ]! b( `) _* g5 w
- $ [ X3 K6 D2 l7 q9 |( }1 B+ F" R
- static uint8_t DMEMORY[DMEM_TOTAL_SIZE];7 m( f) A" F( Z3 K9 W. t
- static DMEM_STATE DMEMS = {0};
" v& j$ ?( S' N4 x. ^+ W
! r' W# U. x. R. `- DMEM *DynMemGet(uint32_t size)
. B- d$ t8 ~( H/ T) ~( { - {
. z! E" i; G5 I6 J% L' S - uint16_t loop = 0;& O0 t' S8 }# q/ b
- uint16_t find = 0;5 L8 w" j8 R7 Y0 T" h. a6 l% D0 ~" z
- uint16_t blk_num_want = 0;+ o- m ~( J0 I3 c3 o
- DMEM * user = NULL;7 v; m: _0 t& B' t! Q/ }! L2 D
- DMEM_APPLY *apply = NULL;% d* c2 D& B6 Y1 w3 j! w. E. ^
-
3 u$ Y, |& z; g _0 c - //申请内存大小不能为0
9 V' C! w/ a1 c) B7 n7 X - if(size == 0) { return NULL; }# R3 {3 y5 D# \7 n! S- y
- //申请内存不可超过总内存大小
# G6 R9 \# ?6 p - if(size > DMEM_TOTAL_SIZE) { return NULL; }
' ?; \# F+ C0 _$ P7 |1 I% Y - //申请内存不可超过剩余内存大小
( b8 W: S# u7 w3 M0 r - if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE) { return NULL; }
6 m' B) U7 k( [3 g - //申请表必须有空余
9 N* B9 f" B9 v6 f# n* M - if(DMEMS.apply_num >= DMEM_BLOCK_NUM) { return NULL; }6 F1 g7 r1 ^' o" q" ]$ v
-
9 a! |1 k4 P! l# O6 Z - //计算所需连续块的个数- l; \) T6 l+ D! Q: m. x
- blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
# x% Q# c8 r5 c; x -
3 T. }6 {1 A, M: I4 s' I - //寻找申请表
* z, e2 Q4 e8 l0 n( n - for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
- M9 l- i7 Z% \6 d3 q. l - {' K- S1 P9 `6 {5 P$ k- p
- if(DMEMS.tb_apply[loop].used == DMEM_FREE)& U: \- H$ Q5 O. P
- {
2 A" X, L% G a& f5 y! I/ C; X* e - apply = &DMEMS.tb_apply[loop]; //申请表已找到& w, I1 Z" ?0 s! @- V" G
- user = &DMEMS.tb_user[loop]; //用户表对应找到+ ~9 b% C% I4 l7 C- _3 |
- user->tb = loop; //申请表编号记录
% h$ g1 b- i& A* C - user->size = blk_num_want * DMEM_BLOCK_SIZE; //分配大小计算& ^8 q- w& ]6 A h/ [1 G
- break;
$ d* V8 B8 G4 {9 n - }1 e4 i& H) y) g& n4 ~
- }
- c- S6 B4 q! A - . t- V% I" ?/ N$ Y; ~
- //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验8 N6 v5 d9 j1 E: L
- if(loop == DMEM_BLOCK_NUM) { return NULL; }
8 C6 z' D9 A: S4 F1 f -
) f7 Z+ U/ y( a) a- e - //寻找连续内存块
- P# Q6 A' C5 h& @1 t- a - for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)2 i+ F z; ~5 w) `) |
- {
6 [" \" L; C: j- C9 w+ Y - if(DMEMS.tb_blk[loop] == DMEM_FREE): _1 ]1 z+ b- [. v% f" G6 K; w
- {//找到第一个空闲内存块- W! ]. U3 [ T6 g. ]4 H& l
- for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++). \+ c/ E, _, ]2 J
- {//找到下一个空闲内存块4 u! ^% H b5 X# ~3 W1 E9 B
- if(DMEMS.tb_blk[loop + find] != DMEM_FREE)3 m* r$ H' I( u% a& o
- {//发现已使用内存块: Q+ }: i' ?9 z' r- s, X& E
- break;* ~" \1 L1 `4 X# h. e8 p2 D2 Z
- }8 j# ~! T. ?9 x* F6 Q. }" p6 C
- }
$ u, c+ z4 @ I; V* C1 ]$ b0 u0 u - if(find >= blk_num_want)4 c. N0 ]& h4 l
- {//寻找到的空闲内存块数目已经够用
( T" F- t2 b( H/ G% ], Y - user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE; //计算申请到的内存的地址8 q! e! `& P" Q& d; _% F
- apply->blk_s = loop; //记录申请到的内存块首序号, o& ]$ [4 m, Q$ I! E1 s
- apply->blk_num = blk_num_want; //记录申请到的内存块数目
8 ^; a9 z$ `9 }9 j" ? - for(find = 0 ; find < apply->blk_num; find++)
4 L! V6 S4 f J1 @4 q - {
) q6 c$ e% d. E - DMEMS.tb_blk[loop + find] = DMEM_USED;$ ^, n6 N: h( B
- }% [! M5 B8 ?5 \0 U3 i
- apply->used = DMEM_USED; //标记申请表已使用
- D& M9 I8 L1 v" \2 S5 Q# T - DMEMS.apply_num += 1;
. X. S1 c& \5 [2 P9 l- @( R - DMEMS.blk_num += blk_num_want;% i2 T& @. F3 ` ^: F
- $ W$ x9 I# X8 @+ l$ a
- return user;
3 z1 f8 M% `! u - }
5 }) S* s C! U; {5 A+ f - else
- I W! ^3 N% Q# e, a9 ^& M& A; I - {//寻找到的空闲内存块不够用,从下一个开始找, ?. Z, o7 ?/ i5 F' F7 Q/ D
- loop += find;
' p+ J* Y. {9 M! R) o - }
1 }' R. o3 L6 [- O/ N - }/ o: k& `3 K* ]: P4 ^! Z
- }
, ~4 V* C9 l& }) g. e$ b% I - 7 N! `2 ?1 b# G. y' o8 W
- //搜索整个内存块,未找到大小适合的空间5 s9 u! S- F5 u+ B! I
- return NULL;
1 @( q2 W; b/ |& ~" S4 F - }% S+ _% v' d# l. Y& W) L2 y
-
" ?" w( T! \! B. e4 Q/ Q# y* N - void DynMemPut(DMEM *user)- J8 p: E# a$ `; r! S
- {
y# o$ }. s3 f4 i$ t$ h6 {* I - uint16_t loop = 0;% B# A/ D7 E o
- //若参数为空,直接返回$ x, U- ~" E0 R/ g
- if(NULL == user) { return; }
9 E! `( c. V, x -
( v5 O4 d* O; c% M - //释放内存空间- b, Y3 S' q* z0 k
- 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++); K# O+ R0 \, S. ~" |8 p
- {& ]. K" {! @) V$ \1 S2 A( U
- DMEMS.tb_blk[loop] = DMEM_FREE;9 _( b0 u8 g6 ?; o4 z
- DMEMS.blk_num -= 1;( D3 \- ]% @, @ d
- }
* \8 f6 v, Z9 |; R# l) O8 M - //释放申请表
( z' i/ b% V% ~1 C4 m - DMEMS.tb_apply[user->tb].used = DMEM_FREE;
# T- I# E( t, V' F0 g. t6 U - DMEMS.apply_num -= 1;
4 {5 v' @4 F, {' o# q - }
复制代码 . H' I7 k; k' W# T" {
|