Keil MDK将变量固定到指定地址_keil 定义数据到指定区域_Little_Star_W的博客-CSDN博客
mdk(keil)怎么查看整个工程占用FLASH及SRAM大小_mdk如何查看程序大小_LYuer_的博客-CSDN博客
F4手册提到(2.3.1)
系统 SRAM 可按字节、半字(16 位)或全字(32 位)访问。读写操作以 CPU 速度执行,
且等待周期为 0。系统 SRAM 分为三个块:
是
大概意思是前面两个块用在高速总线上,片上外设的寄存器这类的可以访问;第三个块没有指定用上,CPU访问;
所以可以得到三个SRAM块使用,一个是正常的SRAM 0x2000 0000一般数据是在这里开始 ,一个是指定0x1000 0000才能使用这个块
外扩的SRAM指定范围为0x6000 0000 到0x6FFF FFFF,大概可以外扩256M=(0x6FFF FFFF-0x6000 0000)/1024/1024 M
开发板上外扩这个芯片IS62WV51216,512*16b=1MB大小的外部内存;
构成:从内存管理结构图,可以知道由内存表和内存块组成,内存块又有大小;
申请查找:从内存表的末端开始查找是否使用;有标记非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
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、申请的内存不能过大,因为内部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