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

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

[复制链接]
STMCU小助手 发布时间:2022-6-3 21:20
    本代码适用于无操作系统的STM32单片机开发,功能强大。
    可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。
    直接复制粘贴如下代码即可:
memory.h:
  1. #ifndef __MEMORY_H__( r+ X+ `# m7 p7 U6 R
  2. #define __MEMORY_H__/ Q% e, O! l' _, o) Q

  3. 2 G" h. G* N# _
  4. #include "stdio.h"
    ' ]$ o1 S. y" D4 c1 O- \/ G
  5. #include "string.h"" d8 L4 x3 u! s% ^8 Z2 a6 F! ~
  6. #include "includes.h"$ v0 ~  B1 V2 u; B7 j" ?3 S
  7. //用户使用& z! z2 _. \5 |
  8. typedef struct
    ( j' m- Q4 ^) _/ a3 z7 a
  9. {8 O- u! x1 A% }
  10.     void    *addr;//申请到的内存的起始地址
    0 C% A/ Q. w% t5 U/ {
  11.     uint32_t size;//申请到的内存的大小,按照块大小分配,大于等于申请大小2 e9 `) O9 ]* F% Z
  12.     uint16_t  tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用
    # y2 S  y, J+ P, G. L; O" `6 f
  13. }DMEM;0 V. T$ Y) c# h* _' q- Q
  14. ( U1 H. ^( M# G1 i
  15. //若返回空,则申请失败
    $ h/ s% d1 o0 K
  16. DMEM *DynMemGet(uint32_t size);& B% ~; {3 Y2 N
  17. void DynMemPut(DMEM *pDmem);& b$ |. h& N( K9 R' m/ y1 s- p9 c
  18. ; A$ i8 A) t0 v# X8 o
  19. #endif //__MEMORY_H__
复制代码

. Z% E4 i: A0 l+ P. N& k- \* k
memory.c:
  1. #include "memory.h"9 B2 s3 T/ q/ I9 L& S
  2. ( e1 x8 n) R7 @* g8 N8 ?: @
  3. #define DMEM_BLOCK_SIZE         256      //内存块大小为128字节7 T: u; J- j( `" E% S7 @/ D
  4. #define DMEM_BLOCK_NUM          20       //内存块个数为40个# O4 {3 t  S6 O+ V
  5. #define DMEM_TOTAL_SIZE         (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)    //内存总大小- i* S0 B1 M9 [- @" r4 W
  6. ! @* c8 r7 T, `6 V1 Y9 [
  7. typedef enum
    - K  M4 \/ [9 T$ k. R$ e
  8. {% ^0 ?, d, Q4 i: y
  9.     DMEM_FREE   = 0,
    " C- T. c. z, ~  k: v) e
  10.     DMEM_USED   = 1,8 g8 E$ g9 I' H, @9 z: Q# W/ l5 Z
  11. }DMEM_USED_ITEM;" C" v6 X* p( {+ P

  12. # e0 P) H2 W4 `
  13. typedef struct: y! O2 d1 I/ }& f3 R: I
  14. {
    ; R, t! v0 _( \. S: i4 h
  15.     DMEM_USED_ITEM   used;       //使用状态
    % u( A( ~! a; k. y, B2 _2 t3 p( d
  16.     uint16_t         blk_s;      //起始块序号
    ( p0 a6 U( H6 e6 m4 {! E
  17.     uint16_t         blk_num;    //块个数
    / |7 H  l2 ^1 m* V: I1 ]
  18. }DMEM_APPLY;! `* A, a7 U, |+ a# E% x) ^6 z

  19. 2 O' r/ h- r, ~0 P, ?& q6 Z5 j
  20. typedef struct
    * P8 K! A4 b0 d1 T' a
  21. {
    8 L2 H( A' o8 C; w
  22.     DMEM_USED_ITEM  tb_blk[DMEM_BLOCK_NUM];; ]. W, b9 v* ]7 v8 S9 T& j2 ?4 L
  23.     DMEM            tb_user[DMEM_BLOCK_NUM];        //用户申请内存信息
    % h, N8 X- S8 Z
  24.     DMEM_APPLY      tb_apply[DMEM_BLOCK_NUM];       //系统分配内存信息
    7 U  J1 A+ k3 e; u
  25.     uint16_t        apply_num;      //内存申请表占用数目
    , z& r9 X! a& @8 v$ G
  26.     uint16_t        blk_num;        //内存块占用数目
    / f0 H; F3 |4 {
  27. }DMEM_STATE;* |+ D3 p5 T% P$ z) a- w/ Y
  28. , m0 U0 I# L+ r) I) u; P
  29. static uint8_t DMEMORY[DMEM_TOTAL_SIZE];
    : r* @; Y( t! z7 p
  30. static DMEM_STATE DMEMS = {0};$ j; x; |$ p9 O3 l

  31. 1 J" T1 t8 ~  E/ V. M8 M
  32. DMEM *DynMemGet(uint32_t size)
    . W2 @, x4 S5 B3 u7 t
  33. {8 M: [2 A% V  H) r/ }5 s; @: y
  34.     uint16_t loop = 0;
    9 B" H7 A6 X* Q7 ^" ?8 p
  35.     uint16_t find = 0;
    2 Z, s; ], |: o& f& L! P
  36.     uint16_t blk_num_want = 0;  S9 ], e; ]3 y1 u' a8 q
  37.     DMEM * user = NULL;
    ' h/ S9 q$ J% I3 s( [5 l: Y
  38.     DMEM_APPLY *apply = NULL;& M' N- E; m' ^# [( Q1 t
  39.     , W. i% ]# }) x% k
  40.     //申请内存大小不能为0( c, ^8 f6 v4 D* [
  41.     if(size == 0)               {   return NULL;    }
    3 l0 n" p& p! \" \
  42.     //申请内存不可超过总内存大小1 z8 F. l/ l7 b4 K3 T1 `+ J, U1 h
  43.     if(size > DMEM_TOTAL_SIZE)  {   return NULL;    }2 |. A6 v! i* X, g! n
  44.     //申请内存不可超过剩余内存大小
    , n. b2 y$ W2 @, S* `
  45.     if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE)   {   return NULL;    }. D+ N0 x1 g% @$ r0 ^5 j6 P; b7 @
  46.     //申请表必须有空余: y0 C  Z& }$ x0 T
  47.     if(DMEMS.apply_num >= DMEM_BLOCK_NUM)   {   return NULL;    }
    6 t& j4 E/ E4 g
  48.    
    0 ^6 `7 M1 {! n6 k0 c
  49.     //计算所需连续块的个数2 Y! y. }. _; O3 D
  50.     blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;9 Z& q0 ?! L, D" Y* ]
  51.    
    7 V# M# j+ i0 t/ ?
  52.     //寻找申请表
    / q- ~# z9 o/ H; ]7 {
  53.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++). N" C5 s3 j3 ~* r/ v6 c4 u7 j; u
  54.     {+ c. `, D2 l" }0 u% z
  55.         if(DMEMS.tb_apply[loop].used == DMEM_FREE)) x. C8 D: u5 A. ]0 Y, B
  56.         {
    3 u1 A2 z' |! l* O- ^! e: U; z
  57.             apply = &DMEMS.tb_apply[loop];                  //申请表已找到$ a% r4 I* i) N. R
  58.             user = &DMEMS.tb_user[loop];                    //用户表对应找到
    9 K* l* Y& D3 y" ^* Q' \& g5 L
  59.             user->tb = loop;                                //申请表编号记录8 G& V( d; m, Q( k! ?- {
  60.             user->size = blk_num_want * DMEM_BLOCK_SIZE;    //分配大小计算8 B' N. S' J# B2 ?" d4 X9 g4 M
  61.             break;
    . ?- |3 t+ W5 [4 P- d. G' Y1 X2 h
  62.         }
    + m: L& ]8 P+ `# N( r" w$ @/ }9 B) t
  63.     }$ i, _1 Y& l/ ?) d
  64.     4 r( Y) ^8 `5 C
  65.     //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验2 h8 E0 _7 A+ ~4 ]8 J7 x0 d/ [
  66.     if(loop == DMEM_BLOCK_NUM)  {   return NULL;    }( g- R2 R6 W1 p
  67.       m3 Y) ]5 P* M& Q7 C8 R( r
  68.     //寻找连续内存块! N% _* e; U. u
  69.     for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)7 D1 s/ A9 @$ G" W, t- b9 M  I
  70.     {. D# \* N0 E4 x7 [5 ^
  71.         if(DMEMS.tb_blk[loop] == DMEM_FREE)
    7 i, n+ R6 T5 @3 ]" g* I
  72.         {//找到第一个空闲内存块# p* |& c* y4 {5 D. c/ `  r2 N* Y
  73.             for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)% y2 S* ^. q/ ]& F
  74.             {//找到下一个空闲内存块/ J, N5 x' F5 [+ O" t
  75.                 if(DMEMS.tb_blk[loop + find] != DMEM_FREE)
    & R! R% X, H; C2 i; S
  76.                 {//发现已使用内存块
    6 M% B4 \6 P6 a7 x0 }' J9 O
  77.                     break;
    : U3 i" |( m( D! W
  78.                 }% \5 M- p* `5 M/ e% j; w
  79.             }1 m" V3 D9 S! {! c; U4 U1 r3 J: C
  80.             if(find >= blk_num_want)
    0 u$ a$ t) }+ Y* J
  81.             {//寻找到的空闲内存块数目已经够用0 Z2 e# X* `" o6 t: y
  82.                 user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE;  //计算申请到的内存的地址+ k0 A! W# E" z' E
  83.                 apply->blk_s = loop;                            //记录申请到的内存块首序号
    7 d! {& s/ Y3 W& V6 J6 T
  84.                 apply->blk_num = blk_num_want;                  //记录申请到的内存块数目
    9 n! \6 s) R' D. s- s
  85.                 for(find = 0 ; find < apply->blk_num; find++), y& Z+ {2 t2 k$ k+ e
  86.                 {
    & f) E3 T* h5 s, a4 `1 a" {' W2 ]4 F5 {
  87.                     DMEMS.tb_blk[loop + find] = DMEM_USED;, m$ p- z, f5 U
  88.                 }
    9 _6 i/ _! ?8 `3 c% h* g
  89.                 apply->used = DMEM_USED;                        //标记申请表已使用9 H2 L: e" S( i6 z: H1 Q! v% x
  90.                 DMEMS.apply_num += 1;
    2 X$ z3 Z/ _! G
  91.                 DMEMS.blk_num += blk_num_want;
    3 P9 f& t: }! z# u& P7 y2 t% Q
  92.                 5 k, v! K! \) W( r+ @
  93.                 return user;5 P/ @9 M4 F' @5 b& C
  94.             }
    7 A  r2 q4 r* C2 J; [
  95.             else+ \+ U% R1 Z! D$ g% U
  96.             {//寻找到的空闲内存块不够用,从下一个开始找
    3 w5 `* P9 a# D. P
  97.                 loop += find;
    ' s+ Z( |1 v9 w6 ~7 d8 R; L/ Y
  98.             }
    / U1 a" I" z$ F+ w1 I3 M1 j
  99.         }
    6 ?9 N+ W' i" g/ u% L0 `
  100.     }  B% M4 W6 W' D: x* h- c. o
  101.     # o3 ~0 ~' r! b
  102.     //搜索整个内存块,未找到大小适合的空间
    . f' P1 N" X+ }! K
  103.     return NULL;) x' e3 ], f0 q/ o5 k
  104. }, E" M8 t0 X1 \- I+ J* ^

  105.   Y7 n  f+ A& @" W5 A4 u
  106. void DynMemPut(DMEM *user)
    ( u* \$ Q" n* T8 X  Y8 W8 f
  107. {  \9 \# L) |, j4 o7 r
  108.     uint16_t loop = 0;, a- P# Z2 h! M! I
  109.     //若参数为空,直接返回
    # R  Q; V* ]* }
  110.     if(NULL == user)    {   return; }8 O. L, V  I  w- d  E: X
  111.     2 S( f8 r/ n' _/ V! J/ h% W
  112.     //释放内存空间
    ) L7 K2 ^. s% p9 y( b
  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++)
    6 Y  y* {3 V- Z1 j  R% |5 f
  114.     {
    1 E" d; C  x8 H* M, X0 b5 x9 r
  115.         DMEMS.tb_blk[loop] = DMEM_FREE;
    4 B7 M: Z7 I7 k* s0 z7 W8 U0 m
  116.         DMEMS.blk_num -= 1;
    - C% x3 ?$ d- R# N
  117.     }
    5 W7 @& y% B9 s+ {
  118.     //释放申请表
    / C) m/ w8 ]/ N0 u1 ]% n( e3 g
  119.     DMEMS.tb_apply[user->tb].used = DMEM_FREE;. H+ h$ p0 P+ H) b) h; y
  120.     DMEMS.apply_num -= 1;4 i4 w  [7 r, p# ?
  121. }
复制代码

, u6 Q! }; t4 e& T
赞 收藏 评论0 发布时间:2022-6-3 21:20

举报

0个回答

所属标签

相似技术帖

官网相关资源

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