STM32 SRAM内存管理

发布者:数据小巨人最新更新时间:2019-06-17 来源: eefocus关键字:STM32  SRAM  内存管理 手机看文章 扫描二维码
随时随地手机看文章

内存池被分割n个内存块,内存表为n的数组,标记内存表(内存块的使用状态)




内存分配-->计算需要m个没存块-->寻找空间内连续的内存区域,标记内存表,返回偏移地址-->计算出返回地址


内存释放-->输入地址-base地址/块size ,得到偏移 ->查内存表知道内存块的大小K->从偏移位置起 K个内存表被清零。


/**

  ******************************************************************************

  * 文件名程: bsp_malloc.c 

  * 作    者: 硬石嵌入式开发团队

  * 版    本: V1.0

  * 编写日期: 2015-10-04

  * 功    能: 动态内存分配管理实现

  ******************************************************************************

  * 说明:

  * 本例程配套硬石stm32开发板YS-F1Pro使用。

  * 

  * 淘宝:

  * 论坛:http://www.ing10bbs.com

  * 

  ******************************************************************************

  */

/* 包含头文件 ----------------------------------------------------------------*/

#include "bsp/malloc/bsp_malloc.h"

 

/* 私有宏定义 ----------------------------------------------------------------*/

/* 私有变量 ------------------------------------------------------------------*/

//内存池(32字节对齐)

__align(32) uint8_t mem1base[MEM1_MAX_SIZE];                  //内部SRAM内存池

__align(32) uint8_t mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000))); //外部SRAM内存池

 

//内存管理表

uint16_t mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP

uint16_t mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+MEM2_MAX_SIZE))); //外部SRAM内存池MAP

 

//内存管理参数    

const uint32_t memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE}; //内存表大小

const uint32_t memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE};       //内存分块大小

const uint32_t memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE};           //内存总大小

 

/* 私有类型定义 --------------------------------------------------------------*/

//内存管理控制器

struct _m_mallco_dev mallco_dev=

{

my_mem_init,              //内存初始化

my_mem_perused,            //内存使用率

mem1base,mem2base,          //内存池

mem1mapbase,mem2mapbase,        //内存管理状态表

0,0,                 //内存管理未就绪

};

 

/* 扩展变量 ------------------------------------------------------------------*/

/* 私有函数原形 --------------------------------------------------------------*/

/* 函数体 --------------------------------------------------------------------*/

 

//复制内存

//*des:目的地址

//*src:源地址

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

void mymemcpy(void *des,void *src,uint32_t n)  

{  

uint8_t *xdes=des;

uint8_t *xsrc=src;

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

}  

 

//设置内存

//*s:内存首地址

//c :要设置的值

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

void mymemset(void *s,uint8_t c,uint32_t count)  

{  

uint8_t *xs = s;  

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

}    

 

//内存管理初始化  

//memx:所属内存块

void my_mem_init(uint8_t memx)  

{  

mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//内存状态表数据清零  

mymemset(mallco_dev.membase[memx], 0,memsize[memx]); //内存池所有数据清零  

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

}  

 

//获取内存使用率

//memx:所属内存块

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

uint8_t my_mem_perused(uint8_t memx)  

{  

uint32_t used=0;  

uint32_t i;  

for(i=0;i {  

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

return (used*100)/(memtblsize[memx]);  

}  

 

 

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

//memx:所属内存块

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

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

uint32_t my_mem_malloc(uint8_t memx,uint32_t size)  

{  

signed long offset=0;  

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

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

uint32_t i;  

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

if(size==0)

return 0XFFFFFFFF;//不需要分配

nmemb=size/memblksize[memx];  //获取需要分配的连续内存块数

if(size%memblksize[memx])nmemb++; 

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

{     

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

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

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

{

for(i=0;i //标注内存块非空 

{  

mallco_dev.memmap[memx][offset+i]=nmemb;  

}  

return (offset*memblksize[memx]);//返回偏移地址  

}

}  

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

}  

 

 

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

//memx:所属内存块

//offset:内存地址偏移

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

uint8_t my_mem_free(uint8_t memx,uint32_t offset)  

{  

int i;  

  

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

{

mallco_dev.init(memx);    

return 1;//未初始化  

}  

 

if(offset {  

int index=offset/memblksize[memx]; //偏移所在内存块号码  

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

for(i=0;i //内存块清零

{  

mallco_dev.memmap[memx][index+i]=0;  

}  

return 0;  

}

else 

return 2;//偏移超区了.  

}  

 

 

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

//memx:所属内存块

//ptr:内存首地址 

void myfree(uint8_t memx,void *ptr)  

{  

uint32_t offset;   

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

offset=(uint32_t)ptr-(uint32_t)mallco_dev.membase[memx];     

my_mem_free(memx,offset); //释放内存     

}  

 

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

//memx:所属内存块

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

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

void *mymalloc(uint8_t memx,uint32_t size)  

{  

uint32_t offset;   

 

offset=my_mem_malloc(memx,size);       

if(offset==0XFFFFFFFF)return NULL;  

else return (void*)((uint32_t)mallco_dev.membase[memx]+offset);  

}  

 

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

//memx:所属内存块

//*ptr:旧内存首地址

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

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

void *myrealloc(uint8_t memx,void *ptr,uint32_t size)  

{  

uint32_t offset;    

offset=my_mem_malloc(memx,size);   

if(offset==0XFFFFFFFF)return NULL;     

else  

   

mymemcpy((void*)((uint32_t)mallco_dev.membase[memx]+offset),ptr,size); //拷贝旧内存内容到新内存   

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

return (void*)((uint32_t)mallco_dev.membase[memx]+offset);  //返回新内存首地址

}  

}

 

/***************************************硬石嵌入式开发团队 *****END OF FILE****/

#ifndef __MALLOC_H__

#define __MALLOC_H__

 

/* 包含头文件 ----------------------------------------------------------------*/

#include

/* 宏定义 --------------------------------------------------------------------*/

#ifndef NULL

#define NULL 0

#endif

 

//定义两个内存池

#define SRAMIN 0 //内部内存池

#define SRAMEX   1 //外部内存池 

 

#define SRAMBANK 2   //定义支持的SRAM块数.

 

//mem1内存参数设定.mem1完全处于内部SRAM里面.

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

#define MEM1_MAX_SIZE   40*1024                //最大管理内存 40K

#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //内存表大小

 

//mem2内存参数设定.mem2的内存池处于外部SRAM里面

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

#define MEM2_MAX_SIZE 960*1024                //最大管理内存960K

#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //内存表大小 

 

/* 类型定义 ------------------------------------------------------------------*/

//内存管理控制器

struct _m_mallco_dev

{

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

uint8_t ( * perused ) ( uint8_t ); //内存使用率

uint8_t  * membase [ SRAMBANK ];    //内存池 管理SRAMBANK个区域的内存

uint16_t * memmap [ SRAMBANK ];    //内存管理状态表

uint8_t    memrdy [ SRAMBANK ]; //内存管理是否就绪

};

 

/* 扩展变量 ------------------------------------------------------------------*/

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

 

/* 函数声明 ------------------------------------------------------------------*/

void mymemset(void *s,uint8_t c,uint32_t count);     //设置内存

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

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

uint32_t my_mem_malloc(uint8_t memx,uint32_t size);   //内存分配(内部调用)

uint8_t my_mem_free(uint8_t memx,uint32_t offset); //内存释放(内部调用)

uint8_t my_mem_perused(uint8_t memx);           //获得内存使用率(外/内部调用) 

 

//用户调用函数

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

void *mymalloc(uint8_t memx,uint32_t size);        //内存分配(外部调用)

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

 

#endif /* __MALLOC_H__ */

 

/***************************************  *****END OF FILE****/


关键字:STM32  SRAM  内存管理 引用地址:STM32 SRAM内存管理

上一篇:STM32F03开发板--系统时钟设置SysTick
下一篇:STM32F4 USART1 TX RX FIFO

推荐阅读最新更新时间:2024-11-08 13:13

STM32信息安全—密码学基本原理(中)
本文的主要内容包括: 哈希函数 完整性和安全性 消息验证 常用算法 Hash/哈希/散列/摘要 函数 哈希函数的功能:对任意输入可以产生固定长度的摘要值 哈希函数的特点:输入的任何改变,都会导致摘要值变化;单向性;低碰撞性 常用哈希函数 消息的“狭义完整性”和“广义完整性” 哈希函数,仅能保证消息的狭义完整性 要保证数据确实是Alice发送的,需要消息认证机制 消息认证 哈希和对称加解密技术的结合之一:HMAC 前提:双方事先约好一个共享密钥 哈希和对称加解密技术的结合之二:AES-GCM AES counter模式+特殊的哈希 输出结果:加密后消息,该消息的认证码标
[单片机]
<font color='red'>STM32</font>信息安全—密码学基本原理(中)
FlyMcu串口ISP下载STM32程序教程
开始写之前也是不能用的,但是为了使用,决定边探索怎么使用边写一篇博客! 最开始用过正点原子的开发板进行ISP下载,感觉挺好用,按照说明就好。 但是正点原子的板子用的是如下的一块电路: 这个电路很简单使用,但是如果你不懂,也很纠结,这里感觉有篇帖子写的很详细,可供大家参考,就不自己解释了,链接如下: http://www.51hei.com/bbs/dpj-35947-1.html 但是,很多人会想用一个USB转串口的小模块下载程序,怎么弄呢? 首先有一个小串口模块,注意转换为的电平是3.3V,不是标准的232电平那种的,东西如下 之后呢,将RXD,TXD,GND,VCC缺一不可的连接到你的STM32板子
[单片机]
FlyMcu串口ISP下载<font color='red'>STM32</font>程序教程
STM32学习笔记之-串口中断接收不定数据buff
今天说一下STM32单片机的接收不定长度字节数据的方法。由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机。 IDLE中断什么时候发生? IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。 如何判断一帧数据结束,就是我们今天讨论的问题。因为很多项目中都要用到这个,因为只有接收到一帧数据以后,你才可以判断这次收了几个字节和每个字节的内容是否符合协议要求。 看了前面IDLE中断的定义,你就会明白了,一帧数据结束后
[单片机]
<font color='red'>STM32</font>学习笔记之-串口中断接收不定数据buff
STM32外设有哪些
[单片机]
意法半导体发布远距离无线微控制器,提高智能计量、智能建筑和工业监控的连接能效
新的STM32系统芯片低功耗,支持多种无线通信协议,简化各种用途的无线系统设计 中国,2023年11月24日 - 服务多重电子应用领域、全球排名前列的半导体公司意法半导体(STMicroelectronics,简称ST;) 发布了一款新的融合无线芯片设计专长与高性能、高能效STM32系统架构的微控制器(MCU)。全新的节能功能将这款无线MCU的电池续航时间延长到15年以上。 在远距离部署的应用领域,包括能源计量、监控设备、报警系统、执行器,以及智能建筑、智能工厂和智能城市的传感器,STM32WL3无线MCU的特别有用,有助于控制功耗,并给工作划分优先级。这些高能效MCU可以改善用户体验,提供服务,减少环境足迹。通过
[嵌入式]
意法半导体发布远距离无线微控制器,提高智能计量、智能建筑和工业监控的连接能效
STM32基础设计(7)---时钟中断(控制LED灯)
本文将介绍STM32的基础时钟,通过时钟中断来控制LED灯的亮灭。 本文的大致思路如下: 1,LED的GPIO口初始化 2,中断初始化 3,时钟初始化 4,编写中断函数 5,编写主函数 首先讲下笔者在做这个设计时得到的教训: 笔者最初是用TIM6基础时钟来实现设计功能,在编写完代码后发现,灯不亮,于是笔者就开始整问题了。先看看代码有没有编写错误,检查一遍后,中断通道使用正确,TIM6配置正确,LED灯的串口也没有问题,中断函数也正常编写了。然后笔者纠结了,他妈代码全对了怎么就运行失败?(原谅笔者爆粗口,因为当时心情的确很不好,可以想象一下,辛辛苦苦桥的代码,没什么毛病,结果到了板子上还运行不
[单片机]
STM32时钟初始化函数SystemInit()详解
花了一天的时间,总算是了解了SystemInit()函数实现了哪些功能,初学STM32,,现记录如下(有理解错误的地方还请大侠指出): 使用的是3.5的库,用的是STM32F107VC,开发环境RVMDK4.23 我已经定义了STM32F10X_CL,SYSCLK_FREQ_72MHz 函数调用顺序: startup_stm32f10x_cl.s(启动文件) SystemInit() SetSysClock () SetSysClockTo72() 初始化时钟用到的RCC寄存器复位值: RCC_CR = 0x0000 xx83; RCC_CFGR = 0x0000 0000;RCC_CIR = 0x0000 0000
[单片机]
<font color='red'>STM32</font>时钟初始化函数SystemInit()详解
在Mac OSX中开发STM32程序
在Mac OSX下编写STM32程序: 1、下载stm32的gcc软件包,参考下面URL: 2、安装moxa NPORT 5110在虚拟Windows中; 3、安装ST Flash Loader 软件; 需要注意的: 1、Mac OSX 需要10.5; 2、NPORT装完要关机重启;
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved