这两天写的一个STM32上的内存管理函数,实现了malloc和free以及remalloc几个函数.还实现了一个内存使用率查询的函数.

思路如下:

将内存分块管理.

内存池等分为固定大小的内存块.

建立一个内存状态表,对应每个块,有多少个块,状态表就有多少个元素,一一对应.

通过状态表的值判断该块内存是否可用(为0则表示可用,为其他值则表示被占用了,而且占用的内存块数量,就是该值的数字)

初始化的时候,状态表的值全0,代表所有的内存块都未被占用.当需要分配的时候,malloc从内存块的最高地址往下查找,查找到连续的空内存大于等于要分配的内存的时候,结束此次分配,返回地址给要分配的指针,完成一次malloc. free的时候,就比较简单了,只要找到所分配的内存对应在状态表的位置,然后把状态表的值清0,及实现free.

内存使用率则通过查询状态表有多少个非0值,来计算占用率.

代码如下:

malloc.h头文件:

#ifndef __MALLOC_H

#define __MALLOC_H

//

//本程序只供学习使用,未经作者许可,不得用于其它任何用途

//ALIENTEK 开发板

//内存管理 代码

//正点原子@ALIENTEK

//技术论坛:www.openedv.com

//创建日期:2011/7/5

//版本:V1.0

//版权所有,盗版必究。

//Copyright(C) 正点原子 2009-2019

//All rights reserved

//********************************************************************************

//没有更新信息

//

typedef unsigned long u32;

typedef unsigned short u16;

typedef unsigned char u8;

#ifndef NULL

#define NULL 0

#endif

#define MEM_BLOCK_SIZE 32 //内存块大小为32字节

#define MAX_MEM_SIZE 10*1024 //最大管理内存 10K

#define MEM_ALLOC_TABLE_SIZE MAX_MEM_SIZE/MEM_BLOCK_SIZE //内存表大小

//内存管理控制器

struct _m_mallco_dev

{

void (*init)(void); //初始化

u8 (*perused)(void); //内存使用率

u8 membase[MAX_MEM_SIZE]; //内存池

u16 memmap[MEM_ALLOC_TABLE_SIZE]; //内存管理状态表

u8 memrdy; //内存管理是否就绪

};

extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义

void mymemset(void *s,u8 c,u32 count); //设置内存

void mymemcpy(void *des,void *src,u32 n);//复制内存

void mem_init(void); //内存管理初始化函数(外/内部调用)

u32 mem_malloc(u32 size); //内存分配(内部调用)

u8 mem_free(u32 offset); //内存释放(内部调用)

u8 mem_perused(void); //获得内存使用率(外/内部调用)

//用户调用函数

void myfree(void *ptr); //内存释放(外部调用)

void *mymalloc(u32 size); //内存分配(外部调用)

void *myrealloc(void *ptr,u32 size); //重新分配内存(外部调用)

#endif

malloc.c文件:

#include "malloc.h"

//

//本程序只供学习使用,未经作者许可,不得用于其它任何用途

//ALIENTEK 开发板

//内存管理 代码

//正点原子@ALIENTEK

//技术论坛:www.openedv.com

//创建日期:2011/7/5

//版本:V1.0

//版权所有,盗版必究。

//Copyright(C) 正点原子 2009-2019

//All rights reserved

//********************************************************************************

//没有更新信息

//

//内存管理控制器

struct _m_mallco_dev mallco_dev=

{

mem_init, //内存初始化

mem_perused,//内存使用率

0, //内存池

0, //内存管理状态表

0, //内存管理未就绪

};

//复制内存

//*des:目的地址

//*src:源地址

//n:需要复制的内存长度(字节为单位)

void memcpy(void *des,void *src,u32 n)

{

u8 *xdes=des;

u8 *xsrc=src;

while(n--)*xdes++=*xsrc++;

}

//设置内存

//*s:内存首地址

//c :要设置的值

//count:需要设置的内存大小(字节为单位)

void memset(void *s,u8 c,u32 count)

{

u8 *xs = s;

while(count--)*xs++=c;

}

//内存管理初始化

void mem_init(void)

{

memset(mallco_dev.membase, 0, sizeof(mallco_dev.membase));//内存池素有数据清零

mallco_dev.memrdy=1;//内存管理初始化OK

}

//获取内存使用率

//返回值:使用率(0~100)

u8 mem_perused(void)

{

u16 used=0;

u32 i;

for(i=0;i

{

if(mallco_dev.memmap[i])used++;

}

return used*100/MEM_ALLOC_TABLE_SIZE;

}

//内存分配(内部调用)

//size:要分配的内存大小(字节)

//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址

u32 mem_malloc(u32 size)

{

signed long offset=0;

u16 nmemb; //需要的内存块数

u16 cmemb=0;//连续空内存块数

u32 i;

if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化

if(size==0)return 0XFFFFFFFF;//不需要分配

nmemb=size/MEM_BLOCK_SIZE; //获取需要分配的连续内存块数

if(size%MEM_BLOCK_SIZE)nmemb++;

for(offset=MEM_ALLOC_TABLE_SIZE-1;offset>=0;offset--)//搜索整个内存控制区

{

if(!mallco_dev.memmap[offset])cmemb++; //连续空内存块数增加

else cmemb=0; //连续内存块清零

if(cmemb==nmemb) //找到了连续nmemb个空内存块

{

for(i=0;i

{

mallco_dev.memmap[offset+i]=nmemb;

}

return (offset*MEM_BLOCK_SIZE);//返回偏移地址

}

}

return 0XFFFFFFFF;//未找到符合分配条件的内存块

}

//释放内存(内部调用)

//offset:内存地址偏移

//返回值:0,释放成功;1,释放失败;

u8 mem_free(u32 offset)

{

int i;

if(!mallco_dev.memrdy)//未初始化,先执行初始化

{

mallco_dev.init();

return 1;//未初始化

}

if(offset

{

int index=offset/MEM_BLOCK_SIZE;//偏移所在内存块号码

int nmemb=mallco_dev.memmap[index]; //内存块数量

for(i=0;i

{

mallco_dev.memmap[index+i]=0;

}

return 0;

}else return 2;//偏移超区了.

}

//释放内存(外部调用)

//ptr:内存首地址

void myfree(void *ptr)

{

u32 offset;

if(ptr==NULL)return;//地址为0.

offset=(u32)ptr-(u32)&mallco_dev.membase;

mem_free(offset);//释放内存

}

//分配内存(外部调用)

//size:内存大小(字节)

//返回值:分配到的内存首地址.

void *mymalloc(u32 size)

{

u32 offset;

offset=mem_malloc(size);

if(offset==0XFFFFFFFF)return NULL;

else return (void*)((u32)&mallco_dev.membase+offset);

}

//重新分配内存(外部调用)

//*ptr:旧内存首地址

//size:要分配的内存大小(字节)

//返回值:新分配到的内存首地址.

void *myrealloc(void *ptr,u32 size)

{

u32 offset;

offset=mem_malloc(size);

if(offset==0XFFFFFFFF)return NULL;

else

{

memcpy((void*)((u32)&mallco_dev.membase+offset),ptr,size);//拷贝旧内存内容到新内存

myfree(ptr); //释放旧内存

return (void*)((u32)&mallco_dev.membase+offset); //返回新内存首地址

}

}

最后测试代码如下:

int main(void)

{

u8 *ptr;

u16 *ptr1;

u32 *ptr2;

u32 *ptr3;

u8 i;

Stm32_Clock_Init(9);//系统时钟设置

delay_init(72); //延时初始化

uart_init(72,9600); //串口1初始化

LED_Init();

//LCD_Init();

ptr=(u8*)mymalloc(100);

if(*ptr)i=0;

i=mallco_dev.perused();//查看使用率

ptr1=(u16*)mymalloc(2*100);

i=mallco_dev.perused();//查看使用率

ptr2=(u32*)mymalloc(4*100);

i=mallco_dev.perused();//查看使用率

myfree(ptr);

i=mallco_dev.perused();//查看使用率

ptr3=(u32*)mymalloc(4*20);

i=mallco_dev.perused();//查看使用率

myfree(ptr1);

i=mallco_dev.perused();//查看使用率

ptr=(u8*)mymalloc(8*32);

myfree(ptr2);

i=mallco_dev.perused();//查看使用率

myfree(ptr3);

i=mallco_dev.perused();//查看使用率

if(i)i=0;

usmart_dev.init();

POINT_COLOR=RED;

while(1)

{

LED0=!LED0;

delay_ms(500);

}

}

欢迎大家在自己的工程里面使用该内存管理代码,如有任何疑问,请回帖!谢谢.

linux stm32 虚拟串口驱动安装,stm32的usb虚拟串口驱动win7系统64位和32位不能正常安装的解决办法!stm32 virtual comport win7(终极解决办法)...相关推荐

  1. 计算机二级安装64位的还是,判断电脑适合装64位还是32位系统需要cpu支持,很多人都搞错了!...

    昨天把系统又重装了一下,猛然发现,我的电脑可以装64位操作系统,而我一直用的是32位操作系统,因为几年前,64位操作系统缺乏驱动,市面上的软件在32位(X86)操作系统兼容性好,而这几年,硬件配置的提 ...

  2. 计算机32位可以安装的游戏,【64位系统能装32位的软件吗】64位系统安装32位软件_64位系统能玩32位游戏吗-系统城...

    2017-11-25 18:15:36 浏览量:1840 能用普通U盘来装系统吗?我们知道光盘是安装系统最传统的工具,普通U盘和光盘一样都是存储工具,那么能将普通U盘制作成装系统的U盘,然后用U盘装系 ...

  3. cnpm 安装文件找不到_大师操作win7系统电脑软件中找不到已经安装字体的恢复步骤...

    大师操作win7系统电脑软件中找不到已经安装字体的恢复步骤 更新日期:2020-10-26 00:55:06作者:win7字体来源:本站整理 不知道大家有没有遇到过win7系统电脑软件中找不到已经安装 ...

  4. linux 64位兼容32位,linux的64位操作系统对32位程序的兼容-全面分析

    1.结构体ioctl_trans: struct ioctl_trans { unsigned long cmd; ioctl_trans_handler_t handler; struct ioct ...

  5. qemu+linux+x86+64,qemu以64位跟32位的方式跑busybox

    qemu以64位和32位的方式跑busybox 两种方式x86_64 和32位的i386方式 -----------x86_64------------------------------------ ...

  6. win10、win7系统64位oracle11g安装教程以及32位plsql连接教程

    win10.win7系统64位oracle11g安装教程以及32位plsql连接教程 转载cxin917 最后发布于2016-02-05 14:16:55 阅读数 24354  收藏 展开 win10 ...

  7. win7已经阻止此发行者在您的计算机上运行软件,win7系统打开特定网站提示“控件无法安装,windows已阻止此软件因为无法验证发行者”如何解决...

    在使用win7系统的过程中,难免会遇到各种问题,有win7系统用户要在电脑中打开一些特定网站或者使用某些网站功能的时候,比如打开工商银行网站时,就会弹出提示"控件无法安装,windows已阻 ...

  8. 服务器能用usb pe安装win7系统,巧用U盘在win8PE下安装win7系统的教程

    U盘的强大功能,以及U盘的便携性让U盘成为大众最受欢迎的安装系统工具,用U盘安装系统的方式逐渐成为一种主流趋势,下面小编就详细地来给大家演示一下,如何用U盘在win8下安装win7系统. 一.U盘启动 ...

  9. linux实用技巧:ubuntu16.04 64位系统安装32位系统兼容包并修改dash(缺省)为bash

    需求 ubuntu16.04 64位系统安装32位系统兼容包并修改dash(缺省)为bash 命令行操作 在linux系统安装32位兼容包:         sudo apt-get install ...

  10. 电脑同时安装32位和64位python_利用anaconda保证64位和32位的python共存

    背景 喵哥想在MFC中调用python脚本,在原来的代码中包含一个只支持x86的库文件(超级核心的文件),原本安装的python是x64的,强行运行程序会出现python头文件里的函数无法解析的错误. ...

最新文章

  1. “计算机之子”winter:我的前端学习路线与方法
  2. Mac OS build caffe2 Error:This file was generated by an older version of protoc which is
  3. 过去式加ed的发音_过去式的变化规律,掌握诀窍了吗?
  4. SQL中cross join,left join,right join ,full join,inner join 的区别
  5. StackExchange.Redis学习笔记(五) 发布和订阅
  6. 使用cloudera manager搭建HUE后的使用,包括Oozie
  7. Facebook 开源 Skip,面向对象+函数式编程语言
  8. 求数组中数的最大值、最小值(C语言)
  9. java 滚动显示信息_滚动显示文本的Java程序
  10. 【hortonworks/registry】registry 如何创建 互相依赖的 schema
  11. python查找关键字所属行_Python查找文件有多牛?男默女泪!!!
  12. python自动化任务_Python任务自动化工具tox使用教程
  13. css的position中absolute和fixed的区别
  14. 【C语言入门教程】4.7 指针的地址分配 - mallocl(), free()
  15. 数字信号处理的fpga实现_数字信号处理的卷积运算实现
  16. 叙述计算机的主要应用领域并各举实例说明,大学计算机基础练习习题集.doc
  17. 阿里云搭建 ftp 服务器
  18. IE11主页被篡改解决方法
  19. 对搜索引擎技术的认识和发展
  20. 适合国人的6款免费远程桌面工具,适用于电脑和手机

热门文章

  1. 卓文萱在北京净万家像街头卖艺似的骗子粉丝做公益绯闻男友辰亦儒看不惯假惺惺模样破口大骂
  2. 2020域名网络安全行业热门事件盘点
  3. 几个Python小案例, 爱上Python编程!
  4. 2021年危险化学品经营单位安全管理人员最新解析及危险化学品经营单位安全管理人员模拟试题
  5. 我的世界服务器信息显示等级,我的世界空岛服务器怎么查方块等级 | 手游网游页游攻略大全...
  6. java计算机毕业设计英语学习网站设计与实现MyBatis+系统+LW文档+源码+调试部署
  7. 谷歌阅读器将于2013年7月1日停止服务,博客订阅转移到邮箱
  8. iOS小技能:动态地给类添加新的方法、实例变量、属性。( 对已经存在的类在扩展中添加自定义的属性)
  9. 猜数字小游戏html,猜数字游戏.html
  10. PHP框架底层源码怎么看,php底层_php框架底层源码怎么看