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

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

[复制链接]
STMCU小助手 发布时间:2022-6-3 21:20
    本代码适用于无操作系统的STM32单片机开发,功能强大。
    可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。
    直接复制粘贴如下代码即可:
memory.h:
  1. #ifndef __MEMORY_H__
    , D" p. Q8 z5 G9 X( C3 q, j: B
  2. #define __MEMORY_H__$ k$ N/ U. u- ]8 L% z
  3. ) f! _4 l( Y) W4 y
  4. #include "stdio.h"
    5 g: U* K$ s( x0 h
  5. #include "string.h"
    2 [# C1 d, e0 }- }
  6. #include "includes.h"
    $ c3 H# }3 q$ b. E9 O
  7. //用户使用
    ( q: W! h& Q( [$ Y% N( O1 u
  8. typedef struct
    . D/ ]4 K/ L& C" s
  9. {5 U% \' F& h' {* Y
  10.     void    *addr;//申请到的内存的起始地址
    8 h7 p* w& T- H. k
  11.     uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小
    8 X) P' v( a6 O" p- R
  12.     uint16_t  tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用
    6 K( u" _; p: V8 Z/ c
  13. }DMEM;
    8 F  s0 }" W4 c8 B& S2 |8 T, B
  14. 7 y& ]# S+ r! B2 L3 @; ~
  15. //若返回空,则申请失败
    0 r# Z8 \$ E8 ]* W
  16. DMEM *DynMemGet(uint32_t size);
    : B* f) J/ d7 e1 N
  17. void DynMemPut(DMEM *pDmem);( C" f( k7 x# j8 b
  18. 4 v4 u2 v; ?5 e" s5 Y
  19. #endif //__MEMORY_H__
复制代码
" B) I. E) o; s6 Q+ t( H
memory.c:
  1. #include "memory.h"
    , G0 J9 ]. W+ l( O1 l) [# y' u
  2.   D% ^. _7 B2 ^7 F" X6 k
  3. #define DMEM_BLOCK_SIZE         256      //内存块大小为128字节0 t  b) w& j+ n5 A: |2 F
  4. #define DMEM_BLOCK_NUM          20       //内存块个数为40个
    1 G3 W6 A, m5 j. |$ j
  5. #define DMEM_TOTAL_SIZE         (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)    //内存总大小
    % s: M+ O4 K+ ]# s& g

  6. ) v! T0 j2 s; V2 O. {
  7. typedef enum# D! Z. N& U7 `6 h" H
  8. {
    % S* x! p) l2 j
  9.     DMEM_FREE   = 0,
    0 `6 l5 b+ g' {/ s$ g6 a
  10.     DMEM_USED   = 1,, j0 ~+ w0 R$ D) z% r$ u
  11. }DMEM_USED_ITEM;5 l! Y+ ]/ b, W' M1 q; I
  12. " \3 w6 _, s8 Z) n% T2 ^
  13. typedef struct3 V" R0 R$ a; v
  14. {
    9 z4 i( H+ o6 v9 ~* j( A
  15.     DMEM_USED_ITEM   used;       //使用状态
    % J% P8 I7 u, n. N- T" L
  16.     uint16_t         blk_s;      //起始块序号
    1 K' P, f: u* F" x1 \
  17.     uint16_t         blk_num;    //块个数/ p. i) Q0 Q4 f: ^8 F
  18. }DMEM_APPLY;
    ( X' i& x6 f! H4 R

  19. 6 P3 t% k+ m  e
  20. typedef struct  e" v1 |: t; S  g3 c: F
  21. {
    3 Y) J2 V; A) s
  22.     DMEM_USED_ITEM  tb_blk[DMEM_BLOCK_NUM];& F8 S1 _; T; o/ Y
  23.     DMEM            tb_user[DMEM_BLOCK_NUM];        //用户申请内存信息
    ' \% u) f6 e5 D. v, c
  24.     DMEM_APPLY      tb_apply[DMEM_BLOCK_NUM];       //系统分配内存信息
    1 n6 w9 e$ J5 s6 b3 |
  25.     uint16_t        apply_num;      //内存申请表占用数目
    ; G& c" e3 F9 z- k5 @$ N7 C
  26.     uint16_t        blk_num;        //内存块占用数目! K  d4 a+ e. h, H; \7 `8 ?- J& d
  27. }DMEM_STATE;3 p+ A( s) s, \6 G* u9 b
  28. : c$ M* h% I" C8 B1 B! T' F
  29. static uint8_t DMEMORY[DMEM_TOTAL_SIZE];
    ' I  k7 ?9 x$ f+ T7 J
  30. static DMEM_STATE DMEMS = {0};! f. n1 N! Y' [: S
  31. 5 \, p% h7 r+ Y& ^
  32. DMEM *DynMemGet(uint32_t size)
    : X5 A2 }& o( f3 N. p7 h6 B
  33. {) U+ N5 ~- Y5 w* b. X2 V: D: T
  34.     uint16_t loop = 0;
    + X% k  [6 ^, u& `, j1 D. _2 {, [
  35.     uint16_t find = 0;& K7 d4 H; }0 k
  36.     uint16_t blk_num_want = 0;2 D$ |2 q# o) C
  37.     DMEM * user = NULL;
    ' f6 W: P1 c$ x9 t5 ^3 W! d+ S
  38.     DMEM_APPLY *apply = NULL;5 n5 c. b& a! ^6 X) Y3 M, v
  39.    
    % C# w7 `& @9 h. h! T) T( Q: e# O8 z( j
  40.     //申请内存大小不能为0$ f3 T" {6 R( Y* o) z; ~5 H1 l
  41.     if(size == 0)               {   return NULL;    }; h6 j+ p; G+ N0 B6 M5 O
  42.     //申请内存不可超过总内存大小
    2 |$ @" n; b" P: S5 t, r
  43.     if(size > DMEM_TOTAL_SIZE)  {   return NULL;    }
    : i& r0 [" q* P
  44.     //申请内存不可超过剩余内存大小; u. i/ u6 l* T
  45.     if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE)   {   return NULL;    }
    1 c% E/ f) j9 g8 K( u
  46.     //申请表必须有空余
    9 k0 r3 M+ h7 a  q1 l- t
  47.     if(DMEMS.apply_num >= DMEM_BLOCK_NUM)   {   return NULL;    }
    ; w9 u; U9 z) W( Z( g' z2 d, o" Q% O
  48.     ' H1 ?# @+ a! ?2 P$ h
  49.     //计算所需连续块的个数
    + J1 N4 ~* O% S0 Y; e3 @: f0 x9 p
  50.     blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
    " A6 v0 S, T! S  [0 ]% W7 n$ {
  51.    
    & s0 F8 W; \% O2 O9 O* X
  52.     //寻找申请表; r. C8 E; V& N4 k, r
  53.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)) J$ i! h+ ]4 g) K4 a+ w$ t6 @
  54.     {
    + q$ t) z' J1 o5 [6 Y# Y4 Y; j
  55.         if(DMEMS.tb_apply[loop].used == DMEM_FREE)
    8 [5 A0 I9 w$ Q& n6 P/ b% B8 X
  56.         {" Y. N3 g& F3 @' r
  57.             apply = &DMEMS.tb_apply[loop];                  //申请表已找到
    2 y9 C: ^* y; ^  \8 q, o2 S
  58.             user = &DMEMS.tb_user[loop];                    //用户表对应找到5 ~7 s  ?7 A9 V( T$ m
  59.             user->tb = loop;                                //申请表编号记录' z$ Z  H" r0 r$ N7 T( }0 h
  60.             user->size = blk_num_want * DMEM_BLOCK_SIZE;    //分配大小计算
    , \, _( d- D1 K4 V; W$ i1 D1 d% T2 O
  61.             break;
    " _8 G( _1 ^$ @
  62.         }
    : ^9 g1 o* V) j0 v! t
  63.     }
    & z3 k- U/ E; Z, Z9 {; K  I- c; W( ^+ U
  64.    
    " s' H0 |* j; @3 a1 N1 a' }+ U0 _
  65.     //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验; F* ]  x  f1 V2 n1 Q
  66.     if(loop == DMEM_BLOCK_NUM)  {   return NULL;    }
    ' ?9 |6 i2 K5 A- G! E. V
  67.     , @4 X9 m0 Z8 G! C
  68.     //寻找连续内存块) i* O- I8 }4 e+ X
  69.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)! K; z  n2 e# O: R8 R; r) ?5 ]9 S6 {
  70.     {. x  e5 Y; g) Q1 }$ D+ d- q
  71.         if(DMEMS.tb_blk[loop] == DMEM_FREE)
    5 N& x' e8 o! D! ^- F% k
  72.         {//找到第一个空闲内存块4 G3 I, T9 {' k6 B  x3 ~
  73.             for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)
    : Z1 ^! }. U5 m
  74.             {//找到下一个空闲内存块) `' z& a1 w3 @
  75.                 if(DMEMS.tb_blk[loop + find] != DMEM_FREE)
    ( `. G' W' \' _3 _! v
  76.                 {//发现已使用内存块3 I3 s/ Z+ E" v( j5 I0 z% ]
  77.                     break;/ p5 x; T) k5 o9 q7 Z" Y& ~
  78.                 }- j3 C/ M- F- s9 L' M
  79.             }* Q5 p) u9 P9 E+ A1 Q4 r4 W1 H  `
  80.             if(find >= blk_num_want)* F9 y* x$ l  p9 Y% ~. i
  81.             {//寻找到的空闲内存块数目已经够用
    0 u7 ]6 H% F6 @  L) p
  82.                 user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE;  //计算申请到的内存的地址
    1 J, a4 ~, d1 X7 z2 ?
  83.                 apply->blk_s = loop;                            //记录申请到的内存块首序号* L, [: E" U3 M6 Z
  84.                 apply->blk_num = blk_num_want;                  //记录申请到的内存块数目
    $ h8 v' N% W3 @8 v8 Z3 {* V
  85.                 for(find = 0 ; find < apply->blk_num; find++), M2 P1 E$ |, y' a5 |5 i7 V) ?
  86.                 {
    : ^0 \9 }+ z9 \; Z
  87.                     DMEMS.tb_blk[loop + find] = DMEM_USED;
    8 Y4 y# ]* J4 }% i. J$ I
  88.                 }
    + N7 A8 c% E  A' f. i, \4 ?+ ^
  89.                 apply->used = DMEM_USED;                        //标记申请表已使用' L  @9 O0 h1 m0 d) |" z  I
  90.                 DMEMS.apply_num += 1;
    3 s( V/ p& _5 B7 K  s2 D
  91.                 DMEMS.blk_num += blk_num_want;, f( a. O* M9 @2 c+ ^/ }; w0 a( e
  92.                   }1 s( ]" e; ^; L, k$ q* s6 R
  93.                 return user;
    $ b: u3 l: F0 k; N/ W; _
  94.             }& A4 \" W# p/ j$ s# M
  95.             else2 G/ T6 x& W7 P/ g- O6 j* N6 n
  96.             {//寻找到的空闲内存块不够用,从下一个开始找& g: d4 [. A: s, I7 U# `) G
  97.                 loop += find;
    / F: T4 D4 L& S  u0 K
  98.             }, p, `2 B& N% r9 l, L
  99.         }
    . {. }  o+ L) H. k9 e1 \
  100.     }: l7 @. n* j% @
  101.     1 t  F) d/ b3 }' [# }
  102.     //搜索整个内存块,未找到大小适合的空间
    2 v1 e. e6 ?4 f* n  g" f
  103.     return NULL;4 ^1 E, j% I$ v5 u; s) y7 W
  104. }
    8 t1 G+ Y0 E; A8 {1 p

  105. 1 x1 u4 @$ d; n" B: Y+ }6 x2 E
  106. void DynMemPut(DMEM *user)
    0 Z- ]) G. y; h
  107. {
    + k* o( P6 \7 t: c3 C* m7 E
  108.     uint16_t loop = 0;# e2 }8 ]6 \' ^$ _. M
  109.     //若参数为空,直接返回
    ( J  y6 ?/ a& h
  110.     if(NULL == user)    {   return; }3 T/ h: ^2 o5 ]9 f! i/ N, |
  111.    
    7 W0 j& a) T- ~- J  S
  112.     //释放内存空间
    ( G  s, Z, ^2 L  T: S- G) G/ @
  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++)
    1 W$ @" _& u2 C) K5 [0 U4 `
  114.     {5 W5 g4 i+ J  t$ I. ^
  115.         DMEMS.tb_blk[loop] = DMEM_FREE;
      ~( Y+ g- n$ [# }6 l* l5 i8 u
  116.         DMEMS.blk_num -= 1;
    ! i; k, h% B& n8 p! j2 ?
  117.     }
    % S! p/ O8 N8 x2 E9 n
  118.     //释放申请表/ y1 y$ ?5 {8 [5 `) g6 u
  119.     DMEMS.tb_apply[user->tb].used = DMEM_FREE;7 Q" X. f, h2 U! ]
  120.     DMEMS.apply_num -= 1;
    ! P& V6 ^! B& T& o7 ~
  121. }
复制代码
: p% Z9 x) {& n2 x" @
赞 收藏 评论0 发布时间:2022-6-3 21:20

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版