你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32单片机内存管理器代码,可直接用于工程

[复制链接]
STMCU小助手 发布时间:2022-6-3 21:20
    本代码适用于无操作系统的STM32单片机开发,功能强大。
    可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。
    直接复制粘贴如下代码即可:
memory.h:
  1. #ifndef __MEMORY_H__! ^3 k2 \4 ]" U( b# b0 x
  2. #define __MEMORY_H__1 B8 J7 Y" s, O9 C: r; _
  3. ' S' ?0 n1 i2 Y
  4. #include "stdio.h"
    / Y% q$ I5 [* z& j, k
  5. #include "string.h"8 ^+ _) _2 ^, o- k& k4 Q
  6. #include "includes.h"
    " z! \; j7 S% b# |
  7. //用户使用
    , R3 m' P- i) U
  8. typedef struct0 x2 h  n: ~4 U1 V7 @' }7 Y
  9. {
    8 x5 \; |: L3 y6 X5 n9 T/ d, _
  10.     void    *addr;//申请到的内存的起始地址/ a: c- M6 K: c) K+ E) f
  11.     uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小
    : S% W8 i; [" {1 v& R
  12.     uint16_t  tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用# T8 }* y; c3 h' `6 q
  13. }DMEM;
    5 A- Y; k2 v4 M

  14. + q3 b8 _% r- v0 b2 X
  15. //若返回空,则申请失败; }5 n; Z5 A+ ?0 {5 h& K
  16. DMEM *DynMemGet(uint32_t size);& b/ T3 x$ T) q4 r
  17. void DynMemPut(DMEM *pDmem);
    / q# V. C5 B+ k% ]. H$ P. P
  18. % l9 H1 g& K$ I" g/ c
  19. #endif //__MEMORY_H__
复制代码

% L5 B8 V$ Q& {& r: _
memory.c:
  1. #include "memory.h"
    , S5 e( P% m+ f& l+ x* e
  2. , F) s8 |) e/ h
  3. #define DMEM_BLOCK_SIZE         256      //内存块大小为128字节% b, q0 o; h6 C2 [* T  ?. B
  4. #define DMEM_BLOCK_NUM          20       //内存块个数为40个  q9 Z; x) X$ v9 K& H
  5. #define DMEM_TOTAL_SIZE         (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)    //内存总大小$ J& h3 {  [- R" n
  6. , w9 z; Z# b5 S% E3 w# J" C
  7. typedef enum& N; Z2 p! w; q8 m' w1 S0 }9 H& l
  8. {
      `. T) \3 [( ^- c8 U
  9.     DMEM_FREE   = 0,
    ( g  {' W& U7 H: X+ H  p8 V
  10.     DMEM_USED   = 1,
    . ~8 Z- ^2 S. M2 m: {. g/ t( }
  11. }DMEM_USED_ITEM;
    : C- {0 h5 R5 g0 U- f, H% x2 |
  12. 4 m% V) Q% T) e/ s  B! F
  13. typedef struct- `$ x2 `/ l" w8 k
  14. {
    & Q& u$ a- \4 R/ {- P: U
  15.     DMEM_USED_ITEM   used;       //使用状态- X* r9 g$ Q. v0 P, ?
  16.     uint16_t         blk_s;      //起始块序号) c' X# U( f7 x  \& Z
  17.     uint16_t         blk_num;    //块个数
    ) r# [3 n% v& V" A) T$ k) V
  18. }DMEM_APPLY;
    7 s. a% R5 n, f6 P/ h9 r
  19. % I" P3 A4 S- \
  20. typedef struct. ^7 i' Y) |5 F3 T( A3 L
  21. {
      r& Q( X7 D( p8 b" {1 p/ Z
  22.     DMEM_USED_ITEM  tb_blk[DMEM_BLOCK_NUM];
    ' Q! K, {1 j* w" Z
  23.     DMEM            tb_user[DMEM_BLOCK_NUM];        //用户申请内存信息
    2 ?8 o- k  ?0 Q, ^& _; ?4 U" f
  24.     DMEM_APPLY      tb_apply[DMEM_BLOCK_NUM];       //系统分配内存信息
    . o1 S6 g% |$ l2 i; {2 c: c
  25.     uint16_t        apply_num;      //内存申请表占用数目: F: m3 z: i' p8 V7 x' N  `- r
  26.     uint16_t        blk_num;        //内存块占用数目
    5 L! j$ e! y/ w3 w8 \! X4 }
  27. }DMEM_STATE;; m' ]! b( `) _* g5 w
  28. $ [  X3 K6 D2 l7 q9 |( }1 B+ F" R
  29. static uint8_t DMEMORY[DMEM_TOTAL_SIZE];7 m( f) A" F( Z3 K9 W. t
  30. static DMEM_STATE DMEMS = {0};
    " v& j$ ?( S' N4 x. ^+ W

  31. ! r' W# U. x. R. `
  32. DMEM *DynMemGet(uint32_t size)
    . B- d$ t8 ~( H/ T) ~( {
  33. {
    . z! E" i; G5 I6 J% L' S
  34.     uint16_t loop = 0;& O0 t' S8 }# q/ b
  35.     uint16_t find = 0;5 L8 w" j8 R7 Y0 T" h. a6 l% D0 ~" z
  36.     uint16_t blk_num_want = 0;+ o- m  ~( J0 I3 c3 o
  37.     DMEM * user = NULL;7 v; m: _0 t& B' t! Q/ }! L2 D
  38.     DMEM_APPLY *apply = NULL;% d* c2 D& B6 Y1 w3 j! w. E. ^
  39.    
    3 u$ Y, |& z; g  _0 c
  40.     //申请内存大小不能为0
    9 V' C! w/ a1 c) B7 n7 X
  41.     if(size == 0)               {   return NULL;    }# R3 {3 y5 D# \7 n! S- y
  42.     //申请内存不可超过总内存大小
    # G6 R9 \# ?6 p
  43.     if(size > DMEM_TOTAL_SIZE)  {   return NULL;    }
    ' ?; \# F+ C0 _$ P7 |1 I% Y
  44.     //申请内存不可超过剩余内存大小
    ( b8 W: S# u7 w3 M0 r
  45.     if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE)   {   return NULL;    }
    6 m' B) U7 k( [3 g
  46.     //申请表必须有空余
    9 N* B9 f" B9 v6 f# n* M
  47.     if(DMEMS.apply_num >= DMEM_BLOCK_NUM)   {   return NULL;    }6 F1 g7 r1 ^' o" q" ]$ v
  48.    
    9 a! |1 k4 P! l# O6 Z
  49.     //计算所需连续块的个数- l; \) T6 l+ D! Q: m. x
  50.     blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
    # x% Q# c8 r5 c; x
  51.    
    3 T. }6 {1 A, M: I4 s' I
  52.     //寻找申请表
    * z, e2 Q4 e8 l0 n( n
  53.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
    - M9 l- i7 Z% \6 d3 q. l
  54.     {' K- S1 P9 `6 {5 P$ k- p
  55.         if(DMEMS.tb_apply[loop].used == DMEM_FREE)& U: \- H$ Q5 O. P
  56.         {
    2 A" X, L% G  a& f5 y! I/ C; X* e
  57.             apply = &DMEMS.tb_apply[loop];                  //申请表已找到& w, I1 Z" ?0 s! @- V" G
  58.             user = &DMEMS.tb_user[loop];                    //用户表对应找到+ ~9 b% C% I4 l7 C- _3 |
  59.             user->tb = loop;                                //申请表编号记录
    % h$ g1 b- i& A* C
  60.             user->size = blk_num_want * DMEM_BLOCK_SIZE;    //分配大小计算& ^8 q- w& ]6 A  h/ [1 G
  61.             break;
    $ d* V8 B8 G4 {9 n
  62.         }1 e4 i& H) y) g& n4 ~
  63.     }
    - c- S6 B4 q! A
  64.     . t- V% I" ?/ N$ Y; ~
  65.     //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验8 N6 v5 d9 j1 E: L
  66.     if(loop == DMEM_BLOCK_NUM)  {   return NULL;    }
    8 C6 z' D9 A: S4 F1 f
  67.    
    ) f7 Z+ U/ y( a) a- e
  68.     //寻找连续内存块
    - P# Q6 A' C5 h& @1 t- a
  69.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)2 i+ F  z; ~5 w) `) |
  70.     {
    6 [" \" L; C: j- C9 w+ Y
  71.         if(DMEMS.tb_blk[loop] == DMEM_FREE): _1 ]1 z+ b- [. v% f" G6 K; w
  72.         {//找到第一个空闲内存块- W! ]. U3 [  T6 g. ]4 H& l
  73.             for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++). \+ c/ E, _, ]2 J
  74.             {//找到下一个空闲内存块4 u! ^% H  b5 X# ~3 W1 E9 B
  75.                 if(DMEMS.tb_blk[loop + find] != DMEM_FREE)3 m* r$ H' I( u% a& o
  76.                 {//发现已使用内存块: Q+ }: i' ?9 z' r- s, X& E
  77.                     break;* ~" \1 L1 `4 X# h. e8 p2 D2 Z
  78.                 }8 j# ~! T. ?9 x* F6 Q. }" p6 C
  79.             }
    $ u, c+ z4 @  I; V* C1 ]$ b0 u0 u
  80.             if(find >= blk_num_want)4 c. N0 ]& h4 l
  81.             {//寻找到的空闲内存块数目已经够用
    ( T" F- t2 b( H/ G% ], Y
  82.                 user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE;  //计算申请到的内存的地址8 q! e! `& P" Q& d; _% F
  83.                 apply->blk_s = loop;                            //记录申请到的内存块首序号, o& ]$ [4 m, Q$ I! E1 s
  84.                 apply->blk_num = blk_num_want;                  //记录申请到的内存块数目
    8 ^; a9 z$ `9 }9 j" ?
  85.                 for(find = 0 ; find < apply->blk_num; find++)
    4 L! V6 S4 f  J1 @4 q
  86.                 {
    ) q6 c$ e% d. E
  87.                     DMEMS.tb_blk[loop + find] = DMEM_USED;$ ^, n6 N: h( B
  88.                 }% [! M5 B8 ?5 \0 U3 i
  89.                 apply->used = DMEM_USED;                        //标记申请表已使用
    - D& M9 I8 L1 v" \2 S5 Q# T
  90.                 DMEMS.apply_num += 1;
    . X. S1 c& \5 [2 P9 l- @( R
  91.                 DMEMS.blk_num += blk_num_want;% i2 T& @. F3 `  ^: F
  92.                 $ W$ x9 I# X8 @+ l$ a
  93.                 return user;
    3 z1 f8 M% `! u
  94.             }
    5 }) S* s  C! U; {5 A+ f
  95.             else
    - I  W! ^3 N% Q# e, a9 ^& M& A; I
  96.             {//寻找到的空闲内存块不够用,从下一个开始找, ?. Z, o7 ?/ i5 F' F7 Q/ D
  97.                 loop += find;
    ' p+ J* Y. {9 M! R) o
  98.             }
    1 }' R. o3 L6 [- O/ N
  99.         }/ o: k& `3 K* ]: P4 ^! Z
  100.     }
    , ~4 V* C9 l& }) g. e$ b% I
  101.     7 N! `2 ?1 b# G. y' o8 W
  102.     //搜索整个内存块,未找到大小适合的空间5 s9 u! S- F5 u+ B! I
  103.     return NULL;
    1 @( q2 W; b/ |& ~" S4 F
  104. }% S+ _% v' d# l. Y& W) L2 y

  105. " ?" w( T! \! B. e4 Q/ Q# y* N
  106. void DynMemPut(DMEM *user)- J8 p: E# a$ `; r! S
  107. {
      y# o$ }. s3 f4 i$ t$ h6 {* I
  108.     uint16_t loop = 0;% B# A/ D7 E  o
  109.     //若参数为空,直接返回$ x, U- ~" E0 R/ g
  110.     if(NULL == user)    {   return; }
    9 E! `( c. V, x
  111.    
    ( v5 O4 d* O; c% M
  112.     //释放内存空间- b, Y3 S' q* z0 k
  113.     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
  114.     {& ]. K" {! @) V$ \1 S2 A( U
  115.         DMEMS.tb_blk[loop] = DMEM_FREE;9 _( b0 u8 g6 ?; o4 z
  116.         DMEMS.blk_num -= 1;( D3 \- ]% @, @  d
  117.     }
    * \8 f6 v, Z9 |; R# l) O8 M
  118.     //释放申请表
    ( z' i/ b% V% ~1 C4 m
  119.     DMEMS.tb_apply[user->tb].used = DMEM_FREE;
    # T- I# E( t, V' F0 g. t6 U
  120.     DMEMS.apply_num -= 1;
    4 {5 v' @4 F, {' o# q
  121. }
复制代码
. H' I7 k; k' W# T" {
收藏 评论0 发布时间:2022-6-3 21:20

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版