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

基于无操作系统的STM32单片机开发的强大代码

[复制链接]
gaosmile 发布时间:2020-12-3 22:21

本代码基于无操作系统的STM32单片机开发,功能强大,可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。直接贴代码:

memory.h:

#ifndef __MEMORY_H__
$ Q6 o4 C* S2 S) O: p6 A, q8 W#define __MEMORY_H__9 V$ }$ A) g  h1 {6 {$ {7 Y
5 A* _! S0 L6 l' j; X5 t
#include "stdio.h"( s8 F1 a  v. _2 u- ]. w
#include "string.h"$ h- D, v5 \; k- Z& n  u
#include "includes.h"
8 ~# e2 @$ v8 D- K- w  D6 k//用户使用7 `/ I$ @: B% B$ k
typedef struct9 u2 o4 L1 P8 b  s* N, Z; T% Z
{' S; W5 f/ X5 i2 m
    void    *addr;      //申请到的内存的起始地址
/ Q" `: p$ ^* @; }    uint32_t size;      //申请到的内存的大小,按照块大小分配,大于等于申请大小4 {1 p" b# Y# i, G1 V; j+ j( n9 P
    uint16_t  tb;       //申请表序号,申请内存时分配,释放内存时使用,用户不使用
8 d4 z/ e5 X) p% i+ b}DMEM;
! \1 i5 [. E1 z& L2 |3 r . J  h6 ~' V5 g1 Q$ X3 g: C" g
//若返回空,则申请失败
& @- M4 M) L# nDMEM *DynMemGet(uint32_t size);# }3 p9 Q; Z2 W' @3 d( q( ]
void DynMemPut(DMEM *pDmem);
0 W% }7 h8 x  m3 B- y( u" y 7 y9 o2 V( k2 r; h) A
#endif //__MEMORY_H__8 ?" }5 A* J! {# B
: B. r5 G( [7 k) T, \: a

memory.c:

#include "memory.h"; n* k1 m2 ^/ H" l

7 t) ^- z- V2 A' V" \* S#define DMEM_BLOCK_SIZE         256      //内存块大小为128字节) F7 V' V2 P5 \4 j, p
#define DMEM_BLOCK_NUM          20       //内存块个数为40个
  A0 ^" @  @& ?6 a7 Z#define DMEM_TOTAL_SIZE         (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)    //内存总大小
1 B* y$ i! |# ? 6 Y) T$ E, v) o+ x, u* d& @
typedef enum
, {; z4 q! s$ z9 K4 v8 R* P/ o, {{
" U/ ], P8 W( A3 b    DMEM_FREE   = 0,! w! j. |+ W' x9 n! J, E6 A9 F
    DMEM_USED   = 1,4 P$ t- q  s& k
}DMEM_USED_ITEM;! G0 p" |7 G, E  K' f

4 Z1 C4 W7 X) A# `7 V2 U( Ptypedef struct0 W+ }$ X: H  \- B, e# K6 C
{& X$ z3 s  i7 @: F+ ^' W; E3 C
    DMEM_USED_ITEM   used;       //使用状态
5 ]  v, w! r& `- E9 H8 K( I( \+ d    uint16_t         blk_s;      //起始块序号) ~' \/ V" i) e# ?. }6 H, b  R
    uint16_t         blk_num;    //块个数
$ C$ M" e$ a9 e}DMEM_APPLY;
; R8 }9 }& d4 `/ k ; j7 R. \0 ?, N. q: K- K5 a
typedef struct. @5 Y: \! d) G$ ^6 }
{" L0 k4 }- e3 ]5 C- `& B* C
    DMEM_USED_ITEM  tb_blk[DMEM_BLOCK_NUM];
0 W. i- C8 t! o0 ]+ S    DMEM            tb_user[DMEM_BLOCK_NUM];        //用户申请内存信息; W/ ^. B' N/ v: O# w& m! y$ |
    DMEM_APPLY      tb_apply[DMEM_BLOCK_NUM];       //系统分配内存信息, T& j0 {% T8 O, K  m
    uint16_t        apply_num;      //内存申请表占用数目1 _: J. [" a& O& \5 k5 t
    uint16_t        blk_num;        //内存块占用数目$ g7 d/ q* [# M) }( _
}DMEM_STATE;7 ?( @' |$ y1 v9 U1 |2 \- A
* `. q, Y- d- i7 ?, J& s$ j4 ~8 g
static uint8_t DMEMORY[DMEM_TOTAL_SIZE];
/ }2 H- M' P. c4 h- q) m" q: istatic DMEM_STATE DMEMS = {0};
; {! E2 H) D) N/ K. _6 b3 H* j! G/ S  c5 }* [9 r) \! k& q7 k: w6 t
DMEM *DynMemGet(uint32_t size)
* E8 B# b- s5 c& a; e{
- `, e1 x* k+ T# `! F8 p4 Z+ z3 f    uint16_t loop = 0;' J; G: z) {" g) n4 e' g
    uint16_t find = 0;
: B! T' h0 C6 q0 m" [  N) ?4 p$ {    uint16_t blk_num_want = 0;( l0 `8 x0 }/ O8 R; w* g5 _
    DMEM * user = NULL;$ O; @5 [8 m3 V4 c4 t5 B- ?& @/ w
    DMEM_APPLY *apply = NULL;
( g. K) ?/ U6 g, k   
! u% ?4 F2 T; J: z    //申请内存大小不能为05 b6 ?/ ]) J+ T/ j% W' \" q0 U
    if(size == 0)               {   return NULL;    }, m( w. N: v/ f' J4 {9 x
    //申请内存不可超过总内存大小
2 t+ M" t. ?( n3 z" |9 h    if(size > DMEM_TOTAL_SIZE)  {   return NULL;    }5 q) c. ?* U# E
    //申请内存不可超过剩余内存大小# \) [) d& O+ F) C* k/ @& t# Q; m+ L
    if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE)   {   return NULL;    }; [  z& l. K# i
    //申请表必须有空余
: f: ^8 B% s; b/ N    if(DMEMS.apply_num >= DMEM_BLOCK_NUM)   {   return NULL;    }
" K0 [; M/ ~' M2 e( l   
- S2 Y, v0 K# Z# D: w8 x- r    //计算所需连续块的个数$ B4 t' c) V  R1 A% n2 Z" L6 W8 r- P4 |
    blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;/ i- E+ r4 p& s4 p( @/ L
   
5 f2 A- J9 K' M. B; b    //寻找申请表
( A1 D: g, S: i1 k6 L    for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
! C' @& X2 w" i+ q1 Q- E/ ^/ v8 a    {
% @2 [3 {6 c$ p' w6 G( ^! |        if(DMEMS.tb_apply[loop].used == DMEM_FREE)
. Z* G7 [6 o' S        {
# U7 S  y  X- M' h7 Z2 S  J            apply = &DMEMS.tb_apply[loop];                  //申请表已找到
( y+ m( o) y- X$ z2 T: I1 q            user = &DMEMS.tb_user[loop];                    //用户表对应找到2 H* |* o- ^  D# |
            user->tb = loop;                                //申请表编号记录
, d7 @+ A  T, [, z' L            user->size = blk_num_want * DMEM_BLOCK_SIZE;    //分配大小计算
$ ]8 Q8 Z! ^/ @            break;4 i& ^4 Z3 t# w. ^
        }
+ t' X( A* r8 i/ N    }
$ g8 e1 c- Q" y: m' w1 w   
7 d2 I) v5 L& W/ G2 Z' {. l7 `    //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验" o: B; }% ]# }0 D% ]. e
    if(loop == DMEM_BLOCK_NUM)  {   return NULL;    }
6 ?# ]) Y( F7 I" G. Q7 J5 O    0 M( _0 t& ~% m0 Z
    //寻找连续内存块
9 N* h% J* W  y) M5 s9 K    for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
' k% p# m& M4 o9 C% ?* T; D    {
& F: u" @- ?1 _: }& k1 ]        if(DMEMS.tb_blk[loop] == DMEM_FREE)+ Z5 ^: o! a3 D; O* g% W
        {//找到第一个空闲内存块
: o) C7 s7 B! S) a            for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)
/ a" w& V8 L$ H! K$ G3 S            {//找到下一个空闲内存块
- d) B0 R% I" D# g' o' D+ R. A                if(DMEMS.tb_blk[loop + find] != DMEM_FREE)! B% G; K4 c* M! a4 X! `' A0 K
                {//发现已使用内存块# U6 [& T' H8 ^+ V& ~" |/ w5 _; X
                    break;/ f+ t+ [  O1 d
                }
# f) C8 b" d( Y            }5 \9 v4 h- \- a, L, o% g
            if(find >= blk_num_want)4 W, q! A3 S4 Z8 f9 h
            {//寻找到的空闲内存块数目已经够用
& e) P9 G3 l6 K& c, [                user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE;  //计算申请到的内存的地址
1 f/ p; h& I% {                apply->blk_s = loop;                            //记录申请到的内存块首序号9 b; p1 t6 j$ @, v4 e( E
                apply->blk_num = blk_num_want;                  //记录申请到的内存块数目
2 C( S- ?/ x/ I                for(find = 0 ; find < apply->blk_num; find++)
$ Q: Y) B6 V& J. x! ~5 V                {
+ C5 N) R: O: }* ^1 b/ u' l                    DMEMS.tb_blk[loop + find] = DMEM_USED;
: ^/ c/ N0 ~0 u9 L' {                }7 C4 ]% A/ m. A4 ^# H
                apply->used = DMEM_USED;                        //标记申请表已使用! \8 A/ Y1 h, d! v! G) k' e% H' E
                DMEMS.apply_num += 1;
& Y" F/ N+ k  s0 U8 t. t5 ?                DMEMS.blk_num += blk_num_want;
  j8 C! U' f7 B3 d                7 o4 E- [0 f" e5 V
                return user;( l$ _  P. B: r( |! Z( \5 g$ k
            }
6 ~7 Q5 X; ?3 @+ ^" A# [$ |) F            else1 ]. V+ U: }# m2 a
            {//寻找到的空闲内存块不够用,从下一个开始找
/ h/ H( Q% e0 A8 h- Y8 z                loop += find;
4 U4 n- u3 Z* c1 [- T            }
: M8 `6 ~. x% M) W. b        }
' m! E: U( D/ |0 [& ^: h9 i. I/ J    }) i) ]- b, H3 M2 p9 H6 X7 P
    / A+ N! q) ?7 F# }, G" b9 }  v
    //搜索整个内存块,未找到大小适合的空间% \5 i4 |" p9 a* y" K
    return NULL;) Z1 m" o- W1 o  K1 }- V' N2 }
}
* }, b( ^8 `) e. c8 B' X
5 v6 f4 w7 @* d3 R) Q/ `' U( N8 ]( g) avoid DynMemPut(DMEM *user)
: I1 |( U" K/ n- U{  M: @" U$ p4 ?0 K  ?& o8 v: F
    uint16_t loop = 0;3 b' Q6 f. u. h3 q
    //若参数为空,直接返回" C$ n+ W3 z# r& u6 G0 R: {
    if(NULL == user)    {   return; }& y; L9 H2 O4 {+ Q2 ~, s
   
7 s& v/ e, H9 ]; \* w    //释放内存空间& U; z* E  m( [9 k$ c, X# ]
    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++)
  Z) b0 z- O9 V  P& P, c: ^! P    {
( x/ Q, M  [/ E  ^: i; A% v        DMEMS.tb_blk[loop] = DMEM_FREE;
0 ~+ |) ]; n* ]6 i0 L5 a2 ~3 T        DMEMS.blk_num -= 1;* h( _8 t8 y. T& y7 U* r* u# x
    }" |# k* A0 X& l2 v* W
    //释放申请表: C4 k5 x. N% k/ h9 z; Y4 Z
    DMEMS.tb_apply[user->tb].used = DMEM_FREE;
9 f- k6 s% M3 r6 q$ V! r    DMEMS.apply_num -= 1;
5 F* z6 B3 b; c' \: A! B) B}
) P' F; N  d6 j# S
收藏 1 评论2 发布时间:2020-12-3 22:21

举报

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