|
本代码适用于无操作系统的STM32单片机开发,功能强大。 可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。 直接复制粘贴如下代码即可: memory.h: - #ifndef __MEMORY_H__( r+ X+ `# m7 p7 U6 R
- #define __MEMORY_H__/ Q% e, O! l' _, o) Q
-
2 G" h. G* N# _ - #include "stdio.h"
' ]$ o1 S. y" D4 c1 O- \/ G - #include "string.h"" d8 L4 x3 u! s% ^8 Z2 a6 F! ~
- #include "includes.h"$ v0 ~ B1 V2 u; B7 j" ?3 S
- //用户使用& z! z2 _. \5 |
- typedef struct
( j' m- Q4 ^) _/ a3 z7 a - {8 O- u! x1 A% }
- void *addr;//申请到的内存的起始地址
0 C% A/ Q. w% t5 U/ { - uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小2 e9 `) O9 ]* F% Z
- uint16_t tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用
# y2 S y, J+ P, G. L; O" `6 f - }DMEM;0 V. T$ Y) c# h* _' q- Q
- ( U1 H. ^( M# G1 i
- //若返回空,则申请失败
$ h/ s% d1 o0 K - DMEM *DynMemGet(uint32_t size);& B% ~; {3 Y2 N
- void DynMemPut(DMEM *pDmem);& b$ |. h& N( K9 R' m/ y1 s- p9 c
- ; A$ i8 A) t0 v# X8 o
- #endif //__MEMORY_H__
复制代码
. Z% E4 i: A0 l+ P. N& k- \* k
memory.c: - #include "memory.h"9 B2 s3 T/ q/ I9 L& S
- ( e1 x8 n) R7 @* g8 N8 ?: @
- #define DMEM_BLOCK_SIZE 256 //内存块大小为128字节7 T: u; J- j( `" E% S7 @/ D
- #define DMEM_BLOCK_NUM 20 //内存块个数为40个# O4 {3 t S6 O+ V
- #define DMEM_TOTAL_SIZE (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) //内存总大小- i* S0 B1 M9 [- @" r4 W
- ! @* c8 r7 T, `6 V1 Y9 [
- typedef enum
- K M4 \/ [9 T$ k. R$ e - {% ^0 ?, d, Q4 i: y
- DMEM_FREE = 0,
" C- T. c. z, ~ k: v) e - DMEM_USED = 1,8 g8 E$ g9 I' H, @9 z: Q# W/ l5 Z
- }DMEM_USED_ITEM;" C" v6 X* p( {+ P
-
# e0 P) H2 W4 ` - typedef struct: y! O2 d1 I/ }& f3 R: I
- {
; R, t! v0 _( \. S: i4 h - DMEM_USED_ITEM used; //使用状态
% u( A( ~! a; k. y, B2 _2 t3 p( d - uint16_t blk_s; //起始块序号
( p0 a6 U( H6 e6 m4 {! E - uint16_t blk_num; //块个数
/ |7 H l2 ^1 m* V: I1 ] - }DMEM_APPLY;! `* A, a7 U, |+ a# E% x) ^6 z
-
2 O' r/ h- r, ~0 P, ?& q6 Z5 j - typedef struct
* P8 K! A4 b0 d1 T' a - {
8 L2 H( A' o8 C; w - DMEM_USED_ITEM tb_blk[DMEM_BLOCK_NUM];; ]. W, b9 v* ]7 v8 S9 T& j2 ?4 L
- DMEM tb_user[DMEM_BLOCK_NUM]; //用户申请内存信息
% h, N8 X- S8 Z - DMEM_APPLY tb_apply[DMEM_BLOCK_NUM]; //系统分配内存信息
7 U J1 A+ k3 e; u - uint16_t apply_num; //内存申请表占用数目
, z& r9 X! a& @8 v$ G - uint16_t blk_num; //内存块占用数目
/ f0 H; F3 |4 { - }DMEM_STATE;* |+ D3 p5 T% P$ z) a- w/ Y
- , m0 U0 I# L+ r) I) u; P
- static uint8_t DMEMORY[DMEM_TOTAL_SIZE];
: r* @; Y( t! z7 p - static DMEM_STATE DMEMS = {0};$ j; x; |$ p9 O3 l
1 J" T1 t8 ~ E/ V. M8 M- DMEM *DynMemGet(uint32_t size)
. W2 @, x4 S5 B3 u7 t - {8 M: [2 A% V H) r/ }5 s; @: y
- uint16_t loop = 0;
9 B" H7 A6 X* Q7 ^" ?8 p - uint16_t find = 0;
2 Z, s; ], |: o& f& L! P - uint16_t blk_num_want = 0; S9 ], e; ]3 y1 u' a8 q
- DMEM * user = NULL;
' h/ S9 q$ J% I3 s( [5 l: Y - DMEM_APPLY *apply = NULL;& M' N- E; m' ^# [( Q1 t
- , W. i% ]# }) x% k
- //申请内存大小不能为0( c, ^8 f6 v4 D* [
- if(size == 0) { return NULL; }
3 l0 n" p& p! \" \ - //申请内存不可超过总内存大小1 z8 F. l/ l7 b4 K3 T1 `+ J, U1 h
- if(size > DMEM_TOTAL_SIZE) { return NULL; }2 |. A6 v! i* X, g! n
- //申请内存不可超过剩余内存大小
, n. b2 y$ W2 @, S* ` - if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE) { return NULL; }. D+ N0 x1 g% @$ r0 ^5 j6 P; b7 @
- //申请表必须有空余: y0 C Z& }$ x0 T
- if(DMEMS.apply_num >= DMEM_BLOCK_NUM) { return NULL; }
6 t& j4 E/ E4 g -
0 ^6 `7 M1 {! n6 k0 c - //计算所需连续块的个数2 Y! y. }. _; O3 D
- blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;9 Z& q0 ?! L, D" Y* ]
-
7 V# M# j+ i0 t/ ? - //寻找申请表
/ q- ~# z9 o/ H; ]7 { - for(loop = 0; loop < DMEM_BLOCK_NUM; loop++). N" C5 s3 j3 ~* r/ v6 c4 u7 j; u
- {+ c. `, D2 l" }0 u% z
- if(DMEMS.tb_apply[loop].used == DMEM_FREE)) x. C8 D: u5 A. ]0 Y, B
- {
3 u1 A2 z' |! l* O- ^! e: U; z - apply = &DMEMS.tb_apply[loop]; //申请表已找到$ a% r4 I* i) N. R
- user = &DMEMS.tb_user[loop]; //用户表对应找到
9 K* l* Y& D3 y" ^* Q' \& g5 L - user->tb = loop; //申请表编号记录8 G& V( d; m, Q( k! ?- {
- user->size = blk_num_want * DMEM_BLOCK_SIZE; //分配大小计算8 B' N. S' J# B2 ?" d4 X9 g4 M
- break;
. ?- |3 t+ W5 [4 P- d. G' Y1 X2 h - }
+ m: L& ]8 P+ `# N( r" w$ @/ }9 B) t - }$ i, _1 Y& l/ ?) d
- 4 r( Y) ^8 `5 C
- //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验2 h8 E0 _7 A+ ~4 ]8 J7 x0 d/ [
- if(loop == DMEM_BLOCK_NUM) { return NULL; }( g- R2 R6 W1 p
- m3 Y) ]5 P* M& Q7 C8 R( r
- //寻找连续内存块! N% _* e; U. u
- for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)7 D1 s/ A9 @$ G" W, t- b9 M I
- {. D# \* N0 E4 x7 [5 ^
- if(DMEMS.tb_blk[loop] == DMEM_FREE)
7 i, n+ R6 T5 @3 ]" g* I - {//找到第一个空闲内存块# p* |& c* y4 {5 D. c/ ` r2 N* Y
- for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)% y2 S* ^. q/ ]& F
- {//找到下一个空闲内存块/ J, N5 x' F5 [+ O" t
- if(DMEMS.tb_blk[loop + find] != DMEM_FREE)
& R! R% X, H; C2 i; S - {//发现已使用内存块
6 M% B4 \6 P6 a7 x0 }' J9 O - break;
: U3 i" |( m( D! W - }% \5 M- p* `5 M/ e% j; w
- }1 m" V3 D9 S! {! c; U4 U1 r3 J: C
- if(find >= blk_num_want)
0 u$ a$ t) }+ Y* J - {//寻找到的空闲内存块数目已经够用0 Z2 e# X* `" o6 t: y
- user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE; //计算申请到的内存的地址+ k0 A! W# E" z' E
- apply->blk_s = loop; //记录申请到的内存块首序号
7 d! {& s/ Y3 W& V6 J6 T - apply->blk_num = blk_num_want; //记录申请到的内存块数目
9 n! \6 s) R' D. s- s - for(find = 0 ; find < apply->blk_num; find++), y& Z+ {2 t2 k$ k+ e
- {
& f) E3 T* h5 s, a4 `1 a" {' W2 ]4 F5 { - DMEMS.tb_blk[loop + find] = DMEM_USED;, m$ p- z, f5 U
- }
9 _6 i/ _! ?8 `3 c% h* g - apply->used = DMEM_USED; //标记申请表已使用9 H2 L: e" S( i6 z: H1 Q! v% x
- DMEMS.apply_num += 1;
2 X$ z3 Z/ _! G - DMEMS.blk_num += blk_num_want;
3 P9 f& t: }! z# u& P7 y2 t% Q - 5 k, v! K! \) W( r+ @
- return user;5 P/ @9 M4 F' @5 b& C
- }
7 A r2 q4 r* C2 J; [ - else+ \+ U% R1 Z! D$ g% U
- {//寻找到的空闲内存块不够用,从下一个开始找
3 w5 `* P9 a# D. P - loop += find;
' s+ Z( |1 v9 w6 ~7 d8 R; L/ Y - }
/ U1 a" I" z$ F+ w1 I3 M1 j - }
6 ?9 N+ W' i" g/ u% L0 ` - } B% M4 W6 W' D: x* h- c. o
- # o3 ~0 ~' r! b
- //搜索整个内存块,未找到大小适合的空间
. f' P1 N" X+ }! K - return NULL;) x' e3 ], f0 q/ o5 k
- }, E" M8 t0 X1 \- I+ J* ^
-
Y7 n f+ A& @" W5 A4 u - void DynMemPut(DMEM *user)
( u* \$ Q" n* T8 X Y8 W8 f - { \9 \# L) |, j4 o7 r
- uint16_t loop = 0;, a- P# Z2 h! M! I
- //若参数为空,直接返回
# R Q; V* ]* } - if(NULL == user) { return; }8 O. L, V I w- d E: X
- 2 S( f8 r/ n' _/ V! J/ h% W
- //释放内存空间
) L7 K2 ^. s% p9 y( b - 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++)
6 Y y* {3 V- Z1 j R% |5 f - {
1 E" d; C x8 H* M, X0 b5 x9 r - DMEMS.tb_blk[loop] = DMEM_FREE;
4 B7 M: Z7 I7 k* s0 z7 W8 U0 m - DMEMS.blk_num -= 1;
- C% x3 ?$ d- R# N - }
5 W7 @& y% B9 s+ { - //释放申请表
/ C) m/ w8 ]/ N0 u1 ]% n( e3 g - DMEMS.tb_apply[user->tb].used = DMEM_FREE;. H+ h$ p0 P+ H) b) h; y
- DMEMS.apply_num -= 1;4 i4 w [7 r, p# ?
- }
复制代码
, u6 Q! }; t4 e& T |