STM32F7xx —— 内存管理

                            STM32F7xx —— 内存管理

 

 

目的:高效、快速的分配,并在适当的时候回收内存资源。最终就是实现malloc和free函数。(实现方法参考原子哥)

#define CONFIG_SRAM_OUT_ENABLE     0typedef enum
{SRAM_TYPE_IN,   // 内部内存池
#if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_YPE_OUT,   // 外部内存池(SDRAM)
#endifSRAM_TYPE_DTCM, // DTCM内存池(此部分SRAM仅仅CPU可以访问!!!)SRAM_TYPE_MAX,  // 最多支持的SRAM块数.
} sram_type_t;// 内部SRAM
#define SRAM_IN_BLOCK_SIZE        64            // 内存块大小为64字节
#define SRAM_IN_MAX_SIZE          (160 * 1024)  // 最大管理内存160K
#define SRAM_IN_ALLOC_TABLE_SIZE  (SRAM_IN_MAX_SIZE / SRAM_IN_BLOCK_SIZE)#if(CONFIG_SRAM_OUT_ENABLE == 1)
// 外部SDRAM里面
#define SRAM_OUT_BLOCK_SIZE       64            // 内存块大小为64字节
#define SRAM_OUT_MAX_SIZE         (100 *1024)   // 最大管理内存100K
#define SRAM_OUT_ALLOC_TABLE_SIZE (SRAM_OUT_MAX_SIZE / SRAM_OUT_BLOCK_SIZE)
#endif// CCM,用于管理DTCM(特别注意,这部分SRAM,仅CPU可以访问!!)
#define SRAM_DTCM_BLOCK_SIZE      64                  //内存块大小为64字节
#define SRAM_DTCM_MAX_SIZE        (100 *1024)             //最大管理内存60K
#define SRAM_DTCM_ALLOC_TABLE_SIZE  (SRAM_DTCM_MAX_SIZE/SRAM_DTCM_BLOCK_SIZE)
//内存池(32字节对齐)
__align(32) uint8_t sram_in_base[SRAM_IN_MAX_SIZE];                                      // 内部SRAM内存池
uint32_t sram_in_map_base[SRAM_IN_ALLOC_TABLE_SIZE];#if(CONFIG_SRAM_OUT_ENABLE == 1)
__align(32) uint8_t sram_out_base[SRAM_OUT_MAX_SIZE] __attribute__((at(0xC01F4000)));   // 外部SDRAM内存池
uint32_t sram_out_map_base[SRAM_OUT_ALLOC_TABLE_SIZE] __attribute__((at(0xC01F4000 + SRAM_OUT_MAX_SIZE))); // 外部SRAM内存池MAP
#endif__align(32) uint8_t sram_dtcm_base[SRAM_DTCM_MAX_SIZE] __attribute__((at(0x20000000))); // 内部DTCM内存池
uint32_t sram_dtcm_map_base[SRAM_DTCM_ALLOC_TABLE_SIZE] __attribute__((at(0x20000000 + SRAM_DTCM_MAX_SIZE))); //内部DTCM内存池MAPstatic const uint32_t memtblsize[SRAM_TYPE_MAX] = {SRAM_IN_ALLOC_TABLE_SIZE,
#if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_OUT_ALLOC_TABLE_SIZE,
#endifSRAM_DTCM_ALLOC_TABLE_SIZE}; //内存表大小static const uint32_t memblksize[SRAM_TYPE_MAX] = {SRAM_IN_BLOCK_SIZE,
#if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_OUT_BLOCK_SIZE,
#endifSRAM_DTCM_BLOCK_SIZE};     //内存分块大小static const uint32_t memsize[SRAM_TYPE_MAX] = {SRAM_IN_MAX_SIZE,
#if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_OUT_MAX_SIZE,
#endifSRAM_DTCM_MAX_SIZE};          //内存总大小void mymem_init(uint8_t type);
uint16_t mymem_perused(uint8_t type);typedef struct
{void (* init)(uint8_t );uint16_t (* perused)(uint8_t);		 // 内存使用率uint8_t 	*membase[SRAM_TYPE_MAX]; // 内存池 管理SRAMBANK个区域的内存uint32_t *memmap[SRAM_TYPE_MAX]; 	 // 内存管理状态表uint8_t  memrdy[SRAM_TYPE_MAX];    // 内存管理是否就绪
} sram_dev_t;//内存管理控制器
static sram_dev_t sram_dev =
{mymem_init,        // 内存初始化mymem_perused,     // 内存使用率sram_in_base,#if(CONFIG_SRAM_OUT_ENABLE == 1)sram_out_base,
#endifsram_dtcm_base,  // 内存池sram_in_map_base,
#if(CONFIG_SRAM_OUT_ENABLE == 1)sram_out_map_base,
#endifsram_dtcm_map_base,0,
#if(CONFIG_SRAM_OUT_ENABLE == 1)0,
#endif0,
};// 内存管理初始化
static void mymem_init(uint8_t memx)
{memset(sram_dev.memmap[memx], 0, memtblsize[memx] * 4); // 内存状态表数据清零sram_dev.memrdy[memx] = 1;                              // 内存管理初始化OK
}// 获取内存使用率
// type:所属内存块
// 返回值:使用率(扩大了10倍,0~1000,代表0.0%~100.0%)
static uint16_t mymem_perused(uint8_t type)
{uint32_t used = 0;uint32_t i;for(i = 0; i < memtblsize[type]; ++i){if(sram_dev.memmap[type][i]){used++;}}return (used * 1000) / (memtblsize[type]);
}// 内存分配(内部调用)
// type:所属内存块
// size:要分配的内存大小(字节)
// 返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
static uint32_t mymem_malloc(uint8_t type, uint32_t size)
{signed long offset = 0;uint32_t nmemb;     // 需要的内存块数uint32_t cmemb = 0; // 连续空内存块数uint32_t i;if(!sram_dev.memrdy[type]){sram_dev.init(type);  // 未初始化,先执行初始化}if(size == 0){return 0xFFFFFFFF;  // 不需要分配}nmemb = size / memblksize[type]; // 获取需要分配的连续内存块数if(size % memblksize[type]){nmemb++;}for(offset = memtblsize[type] - 1; offset >= 0; offset--) // 搜索整个内存控制区{if(!sram_dev.memmap[type][offset]){cmemb++;    // 连续空内存块数增加}else{cmemb = 0;  // 连续内存块清零}if(cmemb == nmemb)                // 找到了连续nmemb个空内存块{for(i = 0; i < nmemb; i++)      // 标注内存块非空{sram_dev.memmap[type][offset + i] = nmemb;}return (offset * memblksize[type]); // 返回偏移地址}}return 0xFFFFFFFF; // 未找到符合分配条件的内存块
}// 释放内存(内部调用)
// type:所属内存块
// offset:内存地址偏移
// 返回值:0,释放成功;1,释放失败;
static uint8_t mymem_free(uint8_t type, uint32_t offset)
{int i;if(!sram_dev.memrdy[type])// 未初始化,先执行初始化{sram_dev.init(type);return 1;// 未初始化}if(offset < memsize[type]) // 偏移在内存池内.{int index = offset / memblksize[type];    // 偏移所在内存块号码int nmemb = sram_dev.memmap[type][index]; // 内存块数量for(i = 0; i < nmemb; i++)                // 内存块清零{sram_dev.memmap[type][index + i] = 0;}return 0;}else{return 2;  // 偏移超区了.}
}void MemInit(uint8_t type)
{memset(sram_dev.memmap[type], 0, memtblsize[type] * 4); // 内存状态表数据清零sram_dev.memrdy[type] = 1;              // 内存管理初始化OK
}// 释放内存(外部调用)
// type:所属内存块
// ptr:内存首地址
void MemFree(uint8_t type, void *ptr)
{uint32_t offset;if(ptr == NULL){return;  // 地址为0.}offset = (uint32_t)ptr - (uint32_t)sram_dev.membase[type];mymem_free(type, offset); // 释放内存
}// 分配内存
void *MemAlloc(uint8_t type, uint32_t size)
{uint32_t offset;offset = mymem_malloc(type, size);if(offset == 0XFFFFFFFF){return NULL;}else{return (void*)((uint32_t)sram_dev.membase[type] + offset);}
}// 重新分配内存
void *MemRealloc(uint8_t type, void *ptr, uint32_t size)
{uint32_t offset;offset = mymem_malloc(type, size);if(offset == 0xFFFFFFFF){return NULL;}else{memcpy((void*)((uint32_t)sram_dev.membase[type] + offset), ptr, size); // 拷贝旧内存内容到新内存MemFree(type, ptr);                                                     // 释放旧内存return (void*)((uint32_t)sram_dev.membase[type] + offset);              // 返回新内存首地址}
}

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465604.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js for in 遍历对象与数组

遍历对象 let obj {q:9,w:5,e:2,t:7,c:3}//for in 遍历对象 key为对象的属性名称,遍历属性值时用[]操作符访问//通过[]操作符为对象添加属性或访问属性时&#xff0c;属性名称可以是任何字符串。for (let key in obj) {console.log(obj的key:,key, obj的value:,obj[key]);} …

前凸后翘的步进电机调速算法~

[导读] 大家好&#xff0c;我是逸珺。今天想分享一种超级实用的步进电机调速算法&#xff0c;这种算法在步进电机调速方案中可以说是一种非常优异的方案。梯形调速算法 为啥需要设计一个调速算法呢&#xff1f;步进电机不是给多少脉冲就动多少步吗&#xff1f;但是带上负载了就…

[转帖]关于win7共享的问题和解答

转自 活动目录SEO 的博客&#xff0c;转载请保留原出处 原文路径 http://gnaw0725.blogbus.com/logs/49380146.html 问题 1、请问现在Win7共享后怎么没有出现共享图标显示&#xff0c;都不知道这个文件夹已经共享过。 2、点击右键取消共享后&#xff0c;文件夹会出现一个锁的标…

STM32F7xx —— FatFS(W25QXX)

STM32F7xx —— FatFS&#xff08;W25QXX&#xff09; 看本章之前请务必先食用&#xff1a;动态内存管理 W25QXX读写 使用经典的fatfs1.4.1&#xff0c;下载源码&#xff0c;和我们用户相关的式diskio.c&#xff0c;实现里面的初始化读写和ioctl。ffconf.h用来配置&#xf…

CentOS 7.3 系统安装配置图解教程

一、安装CentOS 7.3 CentOS 7.x系列只有64位系统&#xff0c;没有32位。生产服务器建议安装CentOS-7-x86_64-Minimal-1611.iso版本 成功引导系统后&#xff0c;会出现下面的界面 界面说明&#xff1a; Install CentOS 7 # 安装CentOS 7 Test this media & install CentOS …

朝花夕拾-不务正业的大学生做了什么比赛?

朝花夕拾&#xff0c;旧事重提之意。恰逢CSDN年终征文&#xff0c;所以写作本文为年终总结&#xff0c;实为大学四年的总结&#xff0c;和CSDN一起成长参与各类竞赛的回忆。四年里和小伙伴们一起辛苦奋斗做了那么多比赛&#xff0c;当比赛结束&#xff0c;那些作品便无人问津了…

虚拟化技术--服务器虚拟化

1、 数据中心服务器的运行现状<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />IT技术日新月异&#xff0c;各项管理、业务与IT的联系日益密切&#xff0c;政府、企事业单位的大型数据中心承担的功能越来越强大&#xff0…

post和get的区别

1. get是从服务器上获取数据&#xff0c;post是向服务器传送数据。2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中&#xff0c;值和表单内各个字段一一对应&#xff0c;在URL中可以看到。post是通过HTTP post机制&#xff0c;将表单内各个字段与其内容放置在HTML …

STM32F7xx —— LAN8720(FreeRTOS+LWIP)

STM32F7xx —— LAN8720 STM32F767自带以太网模块&#xff0c;需要外接PHY芯片&#xff0c;完成以太网通信&#xff08;MII/RMII接口&#xff09;。LAN8720详细资料看手册。LWIP:1.4.1 FreeRTOS V8.2.3。 #define ETH_CHANNEL ETH #define ETH_PREEMPT_PRIO …

我是在这里学到的Linux知识的

-上图是读者朋友圈照片&#xff0c;已咨询原创作者这是一个群友分享的学习资料&#xff0c;确实很棒。今天在上班&#xff0c;临近下班的时候&#xff0c;我到茶水间打水&#xff0c;当时下比较大的雨&#xff0c;从里面向外面看出去&#xff0c;看到蒙胧胧的一片&#xff0c;春…

c#字符型转化为asc_wap站 utf-8与 gb2312字符编码的转化函数

一般的wap站的编码都是<?xml version"1.0" encoding"utf-8"?>&#xff0c;所以用form 或者a 传递参数时会遇到乱码&#xff0c;在调用页面无法读取正确的中文字符&#xff0c;可以用一下的函数编译&#xff0c;转化成中文&#xff0c;然后调用Func…

Suct(一)

网址&#xff1a;https://github.com/ScutGame/Scut/wiki 优点&#xff1a;免费&#xff0c;教程多&#xff0c;又有Demo 贼好 【服务器框架层次结构图解】 &#xff08;好厉害~&#xff09; 【一、配置好 IIS Web 服务器】 1. 打开 控制面板 -> 程序和功能 -> 打开或关…

MATLAB —— 基础语法

MATLAB —— 基础语法 目录 MATLAB —— 基础语法 一、基础语法 1、常用的运算符 2、常用特殊变量和常数 3、变量 4、向量 5、矩阵 6、帮助手册 二、基础命令&#xff08;与Linux和DOS命令类似&#xff09; 1、会话管理命令 2、系统命令 3、输入输出命令 4、向量&…

VS2010中不可忽视的部分——VSTO

今天是Visual Studio 2010正式发布的日子&#xff0c;刚刚看了相关的新闻和介绍&#xff0c;感觉上相比Visual Studio 2008来说&#xff0c;又有了不少新的改变和创新&#xff0c;不管是炒作概念也好&#xff0c;炒作想法也罢&#xff0c;但都是想法设法地为我们这些辛苦的程序…

网校系统推荐eduline_网校系统的各项功能的用处

网校系统中有许多的子系统&#xff0c;其中众所周知也是相对重要的两个子系统&#xff0c;一个考试系统&#xff0c;一个直播系统&#xff0c;今天未来云校就来讲讲这两个子系统以及这两个子系统和网校系统的联系。在线模拟考试系统与网校系统大家都知道考试相对于学员、老师和…

学习 Linux/C/C++ 必备资料

在这个信息过载的时代&#xff0c;质量往往比数量更为重要&#xff01;接下来给你推荐的&#xff0c;是我私藏很久的几个有态度、有意思、有质量的优质公号。学习 Linux/C/C 必备&#xff01;快来关注&#xff0c;在这里看见另一种可能&#xff01;开发内功修炼公众号「开发内功…

emmc固件开发_UP2开发板简易开箱(二)

在 老狼 的x86开源硬件群里面抽中了一个UP2开发板&#xff0c;时间已经过去半年多了&#xff0c;实在惭愧&#xff0c;其中一部分原因是菜&#xff0c;菜是原罪。现接上一位抽中UP2的大佬 Jiaao Bai 的文章&#xff0c;本文就叫UP2开发板简易开箱&#xff08;二&#xff09;。一…

MATLAB —— 向量,矩阵,数组

MATLAB —— 向量&#xff0c;矩阵&#xff0c;数组 目录 MATLAB —— 向量&#xff0c;矩阵&#xff0c;数组 一、向量 1、向量定义 2、引用向量元素 3、向量运算 二、矩阵 1、矩阵定义 2、引用矩阵 3、矩阵运算 三、数组 一、向量 1、向量定义 向量是数字的一维数…

as的使用技巧及注意点

都是在项目中总结的&#xff0c;经过实践的&#xff0c;在flex2 as3下使用的。as调jsExternalInterface.call("js函数名",参数&#xff1a;数组);&#xff08;可以接收返回值&#xff09;js调asas&#xff1a;ExternalInterface.addCallback("js中使用的函数名&…

vue基础(学习官方文档)

基础 介绍 是什么 是一套用于构建用户界面的渐进式框架声明式渲染 <div id"app">{{ message }}</div>var app new Vue({el: #app,data: {message: Hello Vue!} })vue 实例 var vm new Vue({// 选项 })一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实…