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

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

[复制链接]
STMCU小助手 发布时间:2022-6-3 21:20
    本代码适用于无操作系统的STM32单片机开发,功能强大。
    可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。
    直接复制粘贴如下代码即可:
memory.h:
  1. #ifndef __MEMORY_H__
    , [# {( [4 W' i% k' B
  2. #define __MEMORY_H__) ?1 x+ L, M7 Z

  3. 5 G; ~/ M9 b2 c( g* ^6 z- x
  4. #include "stdio.h"& R& t! X0 }6 b; L- s+ ?" b
  5. #include "string.h"
    8 g  D( y" y6 b& X
  6. #include "includes.h"
    8 X; X" e8 ]" f. S% y
  7. //用户使用
      w5 u, d: U5 x
  8. typedef struct4 ^7 u! \: Z* K2 E- w& _7 I
  9. {
    # K  n; q! A% h( V" I' `% ?
  10.     void    *addr;//申请到的内存的起始地址
    ! o8 |0 R+ w" _* r0 i. F3 A+ A
  11.     uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小
    , e3 m( ^1 q9 i$ A  l# c# O
  12.     uint16_t  tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用# a1 E8 G6 y) B3 \" N
  13. }DMEM;& h) ~9 c- N  P6 w. e
  14. # A: N! E! q- T1 n2 s
  15. //若返回空,则申请失败
    ! n& @) c6 p0 l( g$ H: k: U( h7 K
  16. DMEM *DynMemGet(uint32_t size);
    & I) ?7 ~6 H1 x: a2 I; D
  17. void DynMemPut(DMEM *pDmem);) T* O+ i' N. Q9 [/ i! i
  18. " C' z5 U( K- D$ ^4 `
  19. #endif //__MEMORY_H__
复制代码
, F6 d( z: @$ W
memory.c:
  1. #include "memory.h"% }4 O( T6 I5 t+ p/ i. }0 a

  2. , N" w9 [, r0 a* z) [  n
  3. #define DMEM_BLOCK_SIZE         256      //内存块大小为128字节
    $ W7 y2 u, ^5 U! _3 J
  4. #define DMEM_BLOCK_NUM          20       //内存块个数为40个
    / Q9 }, F  ?. @5 _3 M4 F
  5. #define DMEM_TOTAL_SIZE         (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)    //内存总大小+ ^' K9 Y+ e% s4 P; k
  6. ; T9 k  {3 }7 i' l8 n
  7. typedef enum
    1 h+ F7 i. h! |# ^
  8. {' h: t  x# _( G0 N
  9.     DMEM_FREE   = 0,
    9 r! m% K* j6 C5 q
  10.     DMEM_USED   = 1,' ~* d2 E- g: G0 g" H! v; L! I8 T
  11. }DMEM_USED_ITEM;/ y+ r4 U/ _1 k2 t9 u" J5 A0 s

  12. 9 y" k8 H: R' c
  13. typedef struct
    ' W( F! C2 a  t0 n! Z, H' I
  14. {
    / j( H3 ]( W) k& o/ C+ e5 f% ]
  15.     DMEM_USED_ITEM   used;       //使用状态
    4 j9 C  f$ d4 D% E( h! A6 J+ x; c
  16.     uint16_t         blk_s;      //起始块序号
    4 [' J1 d1 m6 ?1 k: S+ p$ H
  17.     uint16_t         blk_num;    //块个数5 T+ U/ t8 g4 i+ M% h
  18. }DMEM_APPLY;3 B3 E- r" x3 ]# L# e/ o: E
  19. . }# O' {* h9 s$ f2 M
  20. typedef struct
    & @' J! j- A7 t: x  T
  21. {6 e: q" R" n4 {6 O  q! Q
  22.     DMEM_USED_ITEM  tb_blk[DMEM_BLOCK_NUM];
    6 s+ X% o; F* u& K/ g
  23.     DMEM            tb_user[DMEM_BLOCK_NUM];        //用户申请内存信息8 Z+ D6 U3 ]) f) ?  R
  24.     DMEM_APPLY      tb_apply[DMEM_BLOCK_NUM];       //系统分配内存信息
    0 `- j+ _7 B+ x% E1 G
  25.     uint16_t        apply_num;      //内存申请表占用数目
    / C2 v6 L- C8 r+ L$ w
  26.     uint16_t        blk_num;        //内存块占用数目
    . G; H0 u5 }$ ], n
  27. }DMEM_STATE;
    6 n6 H! F2 l" v; c

  28. 1 y, i( O# d  Q: h: C* }; b) a
  29. static uint8_t DMEMORY[DMEM_TOTAL_SIZE];
    4 B' m+ C6 C2 x% l& o' P1 |% Q
  30. static DMEM_STATE DMEMS = {0};
    % v2 l- x9 ^* J8 b/ F3 I0 O$ d7 u: \
  31. / W- N, f) |# k% B. w8 x
  32. DMEM *DynMemGet(uint32_t size)& N( X; n1 o0 _4 b0 e
  33. {0 [  ?% M% W* Y/ k
  34.     uint16_t loop = 0;% V. T! |$ L9 V# A8 f
  35.     uint16_t find = 0;0 `! d0 A1 Y4 C$ l4 p3 Y8 y' N
  36.     uint16_t blk_num_want = 0;
    # n' i5 ?; C, u1 m( B; u6 K2 P
  37.     DMEM * user = NULL;$ ^2 S# B: y8 s& J' f- l
  38.     DMEM_APPLY *apply = NULL;
    8 c7 V0 o! L; r, A7 d
  39.     8 C- D; }" K) L/ R6 ^; k4 w
  40.     //申请内存大小不能为0
    3 ~1 u  o* V9 s6 {
  41.     if(size == 0)               {   return NULL;    }% V2 l4 m% }# c$ s  N& O5 [; _
  42.     //申请内存不可超过总内存大小, G/ E: J9 A3 ~7 w3 H3 S
  43.     if(size > DMEM_TOTAL_SIZE)  {   return NULL;    }  ?, [& m2 }* }0 |2 Z) D7 r
  44.     //申请内存不可超过剩余内存大小
    0 b$ a/ a" y& x3 K2 B& z
  45.     if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE)   {   return NULL;    }
    0 ?8 O  o6 o/ C( ?. W* \4 u3 Q  [
  46.     //申请表必须有空余) h* ?4 u0 C# f' P# {, h
  47.     if(DMEMS.apply_num >= DMEM_BLOCK_NUM)   {   return NULL;    }( L9 P- b9 G1 z) R* r7 @/ t
  48.    
    + l5 H, ^% c) }5 O" r% E
  49.     //计算所需连续块的个数
    ; R/ p7 l' n0 R9 F
  50.     blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
    * L3 H- M  ~& V1 B# X  k9 C  Z
  51.    
    9 p/ Z( @* p# s; s) `
  52.     //寻找申请表. @3 w6 J9 E  X' z
  53.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
    # e9 t$ E; X4 E7 I% b
  54.     {
    , w2 N5 y% j( o- F/ b& c1 a; S* n
  55.         if(DMEMS.tb_apply[loop].used == DMEM_FREE)& U' A5 n2 e. J/ e% ~
  56.         {
    9 y# ], _) N6 p2 f
  57.             apply = &DMEMS.tb_apply[loop];                  //申请表已找到( c" e6 V. K; a* h$ `5 O1 g+ d
  58.             user = &DMEMS.tb_user[loop];                    //用户表对应找到
    , P- C( J, d# A" v6 H
  59.             user->tb = loop;                                //申请表编号记录4 \. ]- z7 P: v6 r/ o% d) `0 \
  60.             user->size = blk_num_want * DMEM_BLOCK_SIZE;    //分配大小计算7 x7 r' J, H: o2 b
  61.             break;
    5 H! V! E" Z0 a
  62.         }' q) Y2 x8 Q" Q
  63.     }' r. V% X; ]5 g' p
  64.     % @1 t# R; e! h7 u. B' @
  65.     //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验  F) o- U- P! h0 P& e8 D
  66.     if(loop == DMEM_BLOCK_NUM)  {   return NULL;    }
    6 f9 Y5 O' @, p/ n8 W
  67.     0 T$ R$ n2 C) I: w4 T
  68.     //寻找连续内存块6 C) s: E! W% e) j/ Q
  69.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
    7 t/ |+ n: s7 J( m, I3 i0 q' N, i4 X
  70.     {
    4 E  E5 R0 E  W$ d. m1 u) N, s: C0 X
  71.         if(DMEMS.tb_blk[loop] == DMEM_FREE)
      G; ^3 L( ]9 F2 c! ]) t' j
  72.         {//找到第一个空闲内存块
    ' o% S+ b& s2 n7 u# X" B- b: f
  73.             for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++); r% n0 y1 f) F6 `% o; N
  74.             {//找到下一个空闲内存块5 V" o% ]% x6 ]; f
  75.                 if(DMEMS.tb_blk[loop + find] != DMEM_FREE)' {7 X/ S7 |2 `8 Z* R/ N
  76.                 {//发现已使用内存块
    9 Q' P1 b! p. e9 p* D9 J: }2 d+ O
  77.                     break;, k& v! s; K7 x  _
  78.                 }
    ; C# i0 \: L# o& N: U6 F5 v1 w8 D
  79.             }
    $ O6 b/ a8 Y7 W
  80.             if(find >= blk_num_want)
    # o2 r5 N; r* A* R% p  C' ^: s
  81.             {//寻找到的空闲内存块数目已经够用
    4 v9 x5 x/ ], S* G' R7 U
  82.                 user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE;  //计算申请到的内存的地址8 T1 {. P2 o9 a7 d9 C
  83.                 apply->blk_s = loop;                            //记录申请到的内存块首序号' L! B4 u0 _5 W( B" m
  84.                 apply->blk_num = blk_num_want;                  //记录申请到的内存块数目1 X7 A% r# j) O9 S' {
  85.                 for(find = 0 ; find < apply->blk_num; find++)
    . U6 G( S* o! `5 q1 E
  86.                 {
    # O- e" m3 l$ U& Q; c0 ~
  87.                     DMEMS.tb_blk[loop + find] = DMEM_USED;! {8 s% a5 @* T' k) ]3 h) N( @
  88.                 }" p8 Z. q, p1 c8 Z6 X+ x
  89.                 apply->used = DMEM_USED;                        //标记申请表已使用
    # P/ t, q! J# `4 @$ d% ?
  90.                 DMEMS.apply_num += 1;2 r1 \! v* q7 ?, _
  91.                 DMEMS.blk_num += blk_num_want;
    ) A4 l7 R7 o% ~: F, F; @
  92.                 9 s' ?+ M2 n! U8 [  p
  93.                 return user;: g' o( S- m" B# \, j4 r
  94.             }& A- u+ z' T  }2 O
  95.             else
    ( `: }0 d1 G% q6 L& r
  96.             {//寻找到的空闲内存块不够用,从下一个开始找2 y& A: E6 Z; }& L
  97.                 loop += find;& c  E2 i) ?. K* v
  98.             }
    * T9 E3 y7 a" e1 A
  99.         }! W0 B3 k0 w& L! D1 P
  100.     }+ d; z' c3 d! }+ [' U
  101.    
    1 |' L! H! [2 V( \  V+ o6 ~- Z* C
  102.     //搜索整个内存块,未找到大小适合的空间
    + b8 P4 r  I- N7 z2 ?; Z
  103.     return NULL;# v$ h; p+ \# u
  104. }
    $ y% Z8 ^' X0 k
  105. * H" J* V& y1 L/ X* R
  106. void DynMemPut(DMEM *user)
    - P4 t# P2 P7 H! ^+ P$ O( k
  107. {# e$ j8 {, \% k' z! Q" _4 D# J
  108.     uint16_t loop = 0;
    1 x" H" A% \3 g. f7 u( Y
  109.     //若参数为空,直接返回3 K- e' J& W  z: Z
  110.     if(NULL == user)    {   return; }: F  M4 A' K2 g
  111.     9 m) G* f  @/ [* a* P
  112.     //释放内存空间
    2 W$ d3 C& Y2 y! @# N8 ^* Q+ S' s. v( \/ r
  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++)
    $ ?' {7 L- x$ Q* x' r5 ^
  114.     {' U* O% ?# P& w: ^. I& R# `
  115.         DMEMS.tb_blk[loop] = DMEM_FREE;
    " b9 a6 [8 _3 b( W" N
  116.         DMEMS.blk_num -= 1;' k$ D- e3 i5 _$ z1 [, ~! |# i  h
  117.     }8 f  p, N; P- X1 T* o- O
  118.     //释放申请表( z( E: c5 Y& S! B8 }
  119.     DMEMS.tb_apply[user->tb].used = DMEM_FREE;
    ' W( a5 {4 t" i
  120.     DMEMS.apply_num -= 1;- _& X, u  Z6 {* T$ n: v
  121. }
复制代码
9 |  p; g2 P/ N
收藏 评论0 发布时间:2022-6-3 21:20

举报

0个回答

所属标签

相似分享

官网相关资源

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