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

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

[复制链接]
STMCU小助手 发布时间:2022-6-3 21:20
    本代码适用于无操作系统的STM32单片机开发,功能强大。
    可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。
    直接复制粘贴如下代码即可:
memory.h:
  1. #ifndef __MEMORY_H__
    + X2 \7 Z( A: L3 j1 a3 s9 |
  2. #define __MEMORY_H__
    ) Y3 @' e1 b& y" ?$ C1 t
  3. : M5 |8 ?( e; z! h  B
  4. #include "stdio.h"$ {! g. O% Q8 w: N8 N
  5. #include "string.h"
    * l$ ?! o9 M0 M% ]3 s0 l6 K
  6. #include "includes.h"
    8 }; Y7 E7 e* T3 \! r
  7. //用户使用
    & }  w  I/ U1 S
  8. typedef struct
    . k4 `. t  f# M: u6 k- ?9 [
  9. {
    ) K/ O( G+ z! b# Z+ }, o! U
  10.     void    *addr;//申请到的内存的起始地址& ]% M) _( L: I" [% K  l
  11.     uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小' ~- V0 u, d  c2 Q
  12.     uint16_t  tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用! y" W1 i* X- \& H! w
  13. }DMEM;
    # |8 a- ~, e, o! X8 r0 ]4 J

  14. 9 z' N) @- ~* a. k& q# G
  15. //若返回空,则申请失败
    / p9 ]9 P( _6 K4 v- m- |
  16. DMEM *DynMemGet(uint32_t size);
      F$ u) a. x; k  j/ k: L
  17. void DynMemPut(DMEM *pDmem);
    2 M1 }4 H. y6 i+ D2 h# }

  18. 5 k, G+ L8 v7 l' @# G* L8 a9 \
  19. #endif //__MEMORY_H__
复制代码
. W  e; P* I/ p9 R- Y8 }
memory.c:
  1. #include "memory.h"
    7 l5 C4 Y6 h. ^% |

  2. # M3 d& c0 c' {) r
  3. #define DMEM_BLOCK_SIZE         256      //内存块大小为128字节
    5 H& q* s* L5 I5 x
  4. #define DMEM_BLOCK_NUM          20       //内存块个数为40个
    & {! K% j: X3 i, v. z
  5. #define DMEM_TOTAL_SIZE         (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)    //内存总大小2 I8 `0 C4 c  Z7 }% C4 r
  6. 2 n0 f4 ^3 q, u
  7. typedef enum
    ; j* H7 Q1 u6 o' j" ~
  8. {' h! Q$ R; o/ L* Y3 C; Y
  9.     DMEM_FREE   = 0,
    ( T% Y) p) N- G1 d
  10.     DMEM_USED   = 1,
    2 L/ {4 m) Y+ d5 o
  11. }DMEM_USED_ITEM;3 o0 O4 n% q. j; X& ~
  12.   p6 J% ?$ T5 d. I' C
  13. typedef struct/ ~6 y0 {1 N; C/ N" Q% A, {" F, W
  14. {
    % d( V* r' j7 g8 E2 t
  15.     DMEM_USED_ITEM   used;       //使用状态2 W; u* O- w) r( w3 T8 {
  16.     uint16_t         blk_s;      //起始块序号
    " t$ s9 Z9 O" p6 C
  17.     uint16_t         blk_num;    //块个数4 K  k1 o/ w# z# h( A
  18. }DMEM_APPLY;
    . v& |% L! V( c) U
  19. 6 e9 k# O5 m- k9 r- j
  20. typedef struct7 L' _3 B+ {' W& a
  21. {0 E3 f* v; n" }6 z. e# W3 l# [: ?3 H: f
  22.     DMEM_USED_ITEM  tb_blk[DMEM_BLOCK_NUM];" d, M9 e/ e! u3 c/ x, T
  23.     DMEM            tb_user[DMEM_BLOCK_NUM];        //用户申请内存信息9 d9 D4 i/ r! [+ a* S! }" z
  24.     DMEM_APPLY      tb_apply[DMEM_BLOCK_NUM];       //系统分配内存信息9 w2 P: E, [# \
  25.     uint16_t        apply_num;      //内存申请表占用数目& F/ v% [, S) h* `
  26.     uint16_t        blk_num;        //内存块占用数目
    / N# A! ?+ C7 ~- ]/ v
  27. }DMEM_STATE;
    2 [. G& t& j6 x" A4 i. m5 l

  28. ' L& z% q# O- P- R
  29. static uint8_t DMEMORY[DMEM_TOTAL_SIZE];, `" R# b- G; A7 p9 S: c* q
  30. static DMEM_STATE DMEMS = {0};
    . m8 D6 S' a* x

  31. ( K2 B; |( Y( |0 n% H: W
  32. DMEM *DynMemGet(uint32_t size)
    1 J. ^, E4 I: a+ g" z' ]
  33. {  b, C/ p: S7 T
  34.     uint16_t loop = 0;% v0 d1 m/ h* r! s% P1 z
  35.     uint16_t find = 0;/ K) u0 g( p" T9 f& i
  36.     uint16_t blk_num_want = 0;
    2 e; U/ H3 D( X5 B( D
  37.     DMEM * user = NULL;
    % O5 D7 \. E/ G( O* `& O
  38.     DMEM_APPLY *apply = NULL;  n; N: F4 T8 U3 p
  39.    
    $ l. w. d1 }& o- C/ A; o! E
  40.     //申请内存大小不能为0
    7 {6 X' J" _! z* \$ V6 L0 w
  41.     if(size == 0)               {   return NULL;    }
    1 T6 `. l  b. `+ I: ]/ m: E
  42.     //申请内存不可超过总内存大小
    8 p" r( w5 C; X) i
  43.     if(size > DMEM_TOTAL_SIZE)  {   return NULL;    }
    , K# @( z2 H0 H+ {5 I
  44.     //申请内存不可超过剩余内存大小
    $ L4 S8 T7 Q% ?- w$ K( l1 a
  45.     if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE)   {   return NULL;    }
    6 k: k% e+ s) _0 z! x$ v0 L
  46.     //申请表必须有空余
    , y7 s8 z$ r5 h1 E! Q' A0 v
  47.     if(DMEMS.apply_num >= DMEM_BLOCK_NUM)   {   return NULL;    }
    $ |  B5 j4 z' F6 i. M5 Y
  48.     . n$ C$ c7 u! h" R4 N2 P$ D
  49.     //计算所需连续块的个数
    ( ^1 u# b; O+ G# D
  50.     blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
    / v3 t% Z$ H6 b3 p+ K& T2 a
  51.    
    ) p0 j  b; i* c) u/ a& Y% b
  52.     //寻找申请表
    9 |$ m# P$ ~7 `, L0 m
  53.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)8 A* ^9 i$ a- o% k6 l. x+ Q$ @
  54.     {- [% C/ r' ]0 i0 H9 e
  55.         if(DMEMS.tb_apply[loop].used == DMEM_FREE), A& p, W  Z- S, J9 F0 y/ _
  56.         {" ?9 s4 f5 R' U( n# e7 a* j
  57.             apply = &DMEMS.tb_apply[loop];                  //申请表已找到
    ) i3 V2 ?: a! O7 v' j: b2 x
  58.             user = &DMEMS.tb_user[loop];                    //用户表对应找到
    6 V1 a5 _5 D8 T9 b% @; a
  59.             user->tb = loop;                                //申请表编号记录
    ) Z/ e! X8 s* v
  60.             user->size = blk_num_want * DMEM_BLOCK_SIZE;    //分配大小计算7 H9 u0 ~: I3 d2 x/ E1 m( t
  61.             break;
    , a; z; K9 U) M" a" b/ R
  62.         }; z4 K' Q$ n1 s  b) ^
  63.     }
      j# m- e; L0 Q( C# t! J
  64.     6 U  y& _3 [% u' p
  65.     //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验9 ~7 }3 J6 \! V" g3 S
  66.     if(loop == DMEM_BLOCK_NUM)  {   return NULL;    }# d) e3 @  D' w3 f
  67.    
    2 J. Q) Z& x( v* M  v2 s
  68.     //寻找连续内存块
    $ G5 f) Y% V3 |! g! A. ]0 R
  69.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
    % T: ?( U! f2 X, M4 ?
  70.     {1 n: L6 x5 V5 @) g
  71.         if(DMEMS.tb_blk[loop] == DMEM_FREE)) u( S  z0 \* {2 P
  72.         {//找到第一个空闲内存块5 ]9 i$ E/ [' c4 s. y
  73.             for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)
    7 d" u: i5 o9 J$ D+ V
  74.             {//找到下一个空闲内存块! D5 A" V1 q! K4 A
  75.                 if(DMEMS.tb_blk[loop + find] != DMEM_FREE)
    : e- u, V3 T+ `( `! h7 Q) h
  76.                 {//发现已使用内存块7 }8 P( K9 Z! P9 A) [
  77.                     break;
    # ?6 Y3 [/ K6 U7 |
  78.                 }
    * j$ z. R7 c1 x. D* K" o$ F
  79.             }
    . ^; o8 ?- ]; }0 A& D
  80.             if(find >= blk_num_want)6 J. g9 r  b+ a% E: B( J0 Q
  81.             {//寻找到的空闲内存块数目已经够用
    % g4 g. Z3 e  r" ^6 k) |
  82.                 user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE;  //计算申请到的内存的地址
    , g, K1 Y2 |- M1 b5 E
  83.                 apply->blk_s = loop;                            //记录申请到的内存块首序号: W5 d5 S8 b4 K8 ^% t4 A9 F
  84.                 apply->blk_num = blk_num_want;                  //记录申请到的内存块数目- _) k$ g( a9 }. c% A7 {: Y6 d
  85.                 for(find = 0 ; find < apply->blk_num; find++)
      F6 L1 u- }- B, C  I) w0 N
  86.                 {) B  E% g8 `  y
  87.                     DMEMS.tb_blk[loop + find] = DMEM_USED;
    ( d; H, A# l! S+ }! A
  88.                 }- y% k- ^$ Q; v) L! G
  89.                 apply->used = DMEM_USED;                        //标记申请表已使用
    5 ^5 R& n( N. {
  90.                 DMEMS.apply_num += 1;- w" m  n$ f1 a/ X
  91.                 DMEMS.blk_num += blk_num_want;
    $ k8 T" k5 `$ u9 \8 m
  92.                
    ( m9 P% w, {/ W  i
  93.                 return user;) q# N( j) G3 }- r( R2 L- f" B
  94.             }1 Y* _  \; P+ y# N0 \$ \4 v
  95.             else
    # W- R5 C. w% ^1 U1 i3 R
  96.             {//寻找到的空闲内存块不够用,从下一个开始找$ \9 t' d% g" t) k5 S/ i
  97.                 loop += find;
    ( e1 h1 Q- C) o8 P( i1 k
  98.             }
      S  ?& G$ G+ f% {
  99.         }7 X" J: `) R4 W* w: Q
  100.     }
    2 D. E/ o& e" m8 D
  101.    
    : @; z; c. J2 j) D
  102.     //搜索整个内存块,未找到大小适合的空间2 U$ d! E" ]  P4 I
  103.     return NULL;
    1 c# C$ @0 B& \' W7 a  J
  104. }) X( _/ r: `( ^( M: O
  105. 5 c- N" O) |7 ]! ~/ H4 c+ i
  106. void DynMemPut(DMEM *user)
    3 X% b& C- W) ]1 e: c5 m7 ?/ j
  107. {
    : A5 n2 w5 S- ^5 O
  108.     uint16_t loop = 0;' I/ |- H5 @  S' ^. e  q
  109.     //若参数为空,直接返回
    3 i! U. Z7 p3 e7 `) b/ k
  110.     if(NULL == user)    {   return; }: s, f6 M% @$ s
  111.     9 K4 `$ O" m0 B' d3 B* r* D: f
  112.     //释放内存空间
    * `* o- O( z/ l
  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++)
    " l: h* u6 _8 ^0 z9 ]. Q/ b6 \2 G% A
  114.     {
    8 b) w# c4 N/ v2 f3 S
  115.         DMEMS.tb_blk[loop] = DMEM_FREE;& \7 Q3 N* j4 K3 z* S
  116.         DMEMS.blk_num -= 1;- P+ Y% i( w1 p0 ?
  117.     }' ]' \! G, F& d! ?+ k6 R+ V
  118.     //释放申请表( g) [# T9 c: f2 t3 t' v) X) U
  119.     DMEMS.tb_apply[user->tb].used = DMEM_FREE;! \1 @, ?7 o! E, a
  120.     DMEMS.apply_num -= 1;9 N; b( i) }5 l' g# T
  121. }
复制代码
) q1 E" I; l$ K6 E$ l
收藏 评论0 发布时间:2022-6-3 21:20

举报

0个回答

所属标签

相似分享

官网相关资源

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