F4内存管理

 指定使用特定地址


Keil MDK将变量固定到指定地址_keil 定义数据到指定区域_Little_Star_W的博客-CSDN博客

 怎么看程序使用了多少SRAM

mdk(keil)怎么查看整个工程占用FLASH及SRAM大小_mdk如何查看程序大小_LYuer_的博客-CSDN博客

SRAM内部管理

F4手册提到(2.3.1)

系统 SRAM 可按字节、半字(16 位)或全字(32 位)访问。读写操作以 CPU 速度执行, 
且等待周期为 0。系统 SRAM 分为三个块:

  • 映射在地址 0x2000 0000 的 112 KB 和 16 KB 块,可供所有 AHB 主控总线访问。
  • 在地址 0x1000 0000 映射的 64 KB 块,只能供 CPU 通过数据总线访问。

大概意思是前面两个块用在高速总线上,片上外设的寄存器这类的可以访问;第三个块没有指定用上,CPU访问;

所以可以得到三个SRAM块使用,一个是正常的SRAM   0x2000 0000一般数据是在这里开始 ,一个是指定0x1000 0000才能使用这个块

外扩SRAM

F4内存管理_第1张图片

外扩的SRAM指定范围为0x6000 0000 到0x6FFF FFFF,大概可以外扩256M=(0x6FFF FFFF-0x6000 0000)/1024/1024   M

开发板上外扩这个芯片IS62WV51216,512*16b=1MB大小的外部内存;

内存管理结构图

F4内存管理_第2张图片

内存管理原理

构成:从内存管理结构图,可以知道由内存表和内存块组成,内存块又有大小;

申请查找:从内存表的末端开始查找是否使用;有标记非0的就已经在使用。

释放:从内存表的申请得到的地址,正向从地址开始清零内存表;

所以程序需要内存池,和内存表;内存表需要16位的,表可管理地址做大可以偏移65535个字节;

需要建立内存池 m字节,需要m/内存块大小*2(16位)字节;

申请内存

uint32_t my_mem_the_malloc(uint8_t memx ,uint32_t size)
{
   signed long offset=0;
	 uint32_t mem_block_num=size/mem_block_size[memx]; //需要的内存分块数
	 uint32_t mem_block_breakup=0;   //块数记录
	 uint32_t i;
	 if(my_mem_mallcoc.memrdy[memx]!=1)my_mem_mallcoc.init(memx);
	 if(size==0) return 0XFFFFFFFF; //如果申请为0返回错误
	 if(size%mem_block_size[memx])//如果有多余的多申请一个块
		       mem_block_num++;
	  for( offset=mem_map_size[memx]-1;offset>=0;offset--   )//从最后位置查找表,一直查找完
		{
		     if(my_mem_mallcoc.memmap[memx][offset] == 0) 
				 {
						mem_block_breakup++;//连续就累加连续个数
				 }else
				 {
						mem_block_breakup=0;//不连续,就记录清零
				 }
				 if(mem_block_num==mem_block_breakup)//如果需要的个数,和查找到连续个数相等,就是查找完成
				 {
							for(i= 0 ;i
  1. 确保初始化和申请大小不为0
  2. 用申请内存字节需要多少个内存表,从表后面开始查询是否使用,直到查询到连续内存表连续未使用。不成功返回,成功就标记内存表,为申请内存表个数的值,返回申请的内存偏移量;
  3. 把偏移量转成地址返回;

释放内存

uint8_t my_mem_the_free(uint8_t memx ,uint32_t offsize)
{
	int i;
  
	if(my_mem_mallcoc.memrdy[memx]==0)
	{
	   my_mem_mallcoc.init(memx);
		 return 1;//内存池没有初始化返回1

	}
	if(offsize
  1. 利用地址转成内存表偏移量
  2. 找到起始内存表把内存表的标数作为数量,把后面的表都清零;

错误经验

1、申请的内存不能过大,因为内部SRAM本身程序也需要用到一些SRAM;

2、外部SRAM需要初始化FSMC,才能使用外扩SRAM

3、使用内部SRAM的默认指定0x2000 0000 ,所以使用外部或者其他SRAM块都需要指定地址

以上如果出现,就会出现死机;

程序

点c文件

#include"my_malloc_1.h"
#include"main.h"

struct m_malloc_struct my_malloc;


//32字节对齐,一个内存块大小32字节 ,指定地址
__ALIGNED(32)  uint8_t mem1base[MEM1_MAX_SIZE];
__ALIGNED(32)  uint8_t mem2base[MEM2_MAX_SIZE] __attribute__((__section(".ARM.__at_0x68000000")));//外部SRAM内存池
__ALIGNED(32)  uint8_t mem3base[MEM3_MAX_SIZE] __attribute__((__section(".ARM.__at_0x10000000")));//内部CCM内存池


uint16_t mem1mapbase[MEM1_ALLOC_TABLE_SIZE];
uint16_t mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((__section(".ARM.__at_0x68018000")  ));//外部SRAM内存管理状态表
uint16_t mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((__section(".ARM.__at_0x1000F000")  ));//内部SRAM内存管理状态表

const uint32_t mem_map_size[SRAMBANK] ={ MEM1_ALLOC_TABLE_SIZE , MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE};//内存表的大小
const uint32_t mem_block_size[SRAMBANK] ={ MEM1_BLOCK_SIZE , MEM2_BLOCK_SIZE ,MEM3_BLOCK_SIZE }; // 内存池分块的大小
const uint32_t mem_max_size[SRAMBANK] ={MEM1_MAX_SIZE , MEM2_MAX_SIZE , MEM3_MAX_SIZE }; //内存池可管理的大小


struct m_malloc_struct my_mem_mallcoc=
{
    my_mem_init,
    my_mem_use_rote,
	  mem1base,mem2base,mem3base,
	  mem1mapbase,mem2mapbase,mem3mapbase,
    
};





void my_mem_init(uint8_t memx )//初始化内存
{
	int i=0;

	for(i=0;i=0;offset--   )//从最后位置查找表,一直查找完
		{
		     if(my_mem_mallcoc.memmap[memx][offset] == 0) 
				 {
						mem_block_breakup++;//连续就累加连续个数
				 }else
				 {
						mem_block_breakup=0;//不连续,就记录清零
				 }
				 if(mem_block_num==mem_block_breakup)//如果需要的个数,和查找到连续个数相等,就是查找完成
				 {
							for(i= 0 ;i

点H文件

#ifndef MY_MALLOC_1_H
#define MY_MALLOC_1_H
#include"main.h"

/***   内存池1        ******/
#define MEM1_BLOCK_SIZE 32   //内存分块大小
#define MEM1_MAX_SIZE 2*1024 //内存最大管理100K
#define MEM1_ALLOC_TABLE_SIZE  MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //内存1的内存表大小


/***   内存池2        ******/
#define MEM2_BLOCK_SIZE 32 //内存分块大小
#define MEM2_MAX_SIZE 9*1024 //内存最大管理96K
#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //内存2的内存表大小


/***   内存池3        ******/
#define MEM3_BLOCK_SIZE 32 //内存分块大小
#define MEM3_MAX_SIZE 6*1024 //内存最大管理96K
#define MEM3_ALLOC_TABLE_SIZE MEM3_MAX_SIZE/MEM3_BLOCK_SIZE //内存2的内存表大小


#define SRAMBANK 3

struct m_malloc_struct 
{
  void ( *init ) (uint8_t);  //函数指针,用来初始化
	uint8_t  (*use_rote)(uint8_t); //函数指针 ,使用率
	uint8_t  *membase[SRAMBANK];  //内存池  SARMBANK个内存池
	uint16_t *memmap[SRAMBANK];   //内存管理表  SARMBANK个
	uint8_t  memrdy[SRAMBANK];    //内存管理,是否就绪

};
extern struct m_malloc_struct my_malloc;

void my_mem_init(uint8_t memx );//初始化内存
uint8_t my_mem_use_rote(uint8_t memx  );//生成使用率
void *mymalloc(uint8_t memx ,uint32_t size);
void myfree(uint8_t memx ,void *p);
#endif

你可能感兴趣的:(stm32,嵌入式硬件,单片机)