微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于STM32原子战舰板内存管理源码

基于STM32原子战舰板内存管理源码

时间:12-01 来源:互联网 点击:

for(offset=memtblsize[memx]-1;offset>

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

一维数组,每个元素对应的实际意义是对应的一个内存块,顺序是offset从1249(高)->

break;

case wake_up: //KEY UP按下

sramx=!sramx;//切换当前malloc/free操作对象

if(sramx)LCD_ShowString(60,170,200,16,16,"SRAMEX");

else LCD_ShowString(60,170,200,16,16,"SRAMIN");

break;

}

if(tp!=p)

{//在内存paddr值处显示:“P Addr:0X%08X”,“0X%08X”以大写16进制显示参数tp(32位),“08”表示8位数。0X AAAA AAAA

//刚进入程序时,因为执行了“mem_init(SRAMIN);”初始化函数,所以p==0;所以LCD不会有显示

//因为程序一开始就有“u8 *tp=0;”,所以若不按下任何按键LCD就不会显示下面的内容(即“if(tp!=p)”控制的显示内容);

tp=p;//PAddr显示的是指针p本身的地址值;指针值是u32类型

sprintf((char*)paddr,"P Addr:0X%08X",(u32)tp);//将指针p本身的地址值在LCD上打印出来即显示

LCD_ShowString(60,230,200,16,16,paddr); //显示p的地址

if(p)

LCD_ShowString(60,250,200,16,16,p);//显示P的内容,即指针p内存储的数据“Memory Malloc Test%03d”

else LCD_Fill(60,250,239,266,WHITE); //p=0,清除显示

}

delay_ms(10);

i++;

if((i%20)==0)//DS0闪烁.

{

LCD_ShowNum(60+96,190,mem_perused(SRAMIN),3,16);//显示内部内存使用率

LCD_ShowNum(60+96,210,mem_perused(SRAMEX),3,16);//显示外部内存使用率

led0=!led0;

}

}

}

总结:通过内存管理的学习,更加深刻的领会到指针是c语言的灵魂,对c语言的知识是一个巩固和提高;同时也学习到了sprintf()函数的运用技巧。

本章希望利用USMART调试内存管理,所以在USMART里面添加了mymalloc和myfree两个函数,用于测试内存分配和内存释放。大家可以通过USMART自行测试。

4,下载验证:

在代码编译成功之后,我们通过下载代码到ALIENTEK战舰STM32开发板上,得到如图所示界面:

可以看到,内外内存的使用率均为0%,说明还没有任何内存被使用,此时我们按下KEY0,就可以看到内部内存被使用5%(每按下一次申请2K的空间,lcd上显示的使用率递增5%;20*2K==40K)了,同时看到下面提示了指针p所指向的地址(其实就是被分配到的内存地址)和内容。多按几次KEY0,可以看到内存使用率持续上升(注意对比p的值,可以发现是递减的,说明是从顶部开始分配内存!),此时如果按下KEY2,可以发现内存使用率降低了5%,但是再按KEY2将不再降低,说明“内存泄露”了。这就是前面提到的对一个指针多次申请内存,而之前申请的内存又没释放,导致的“内存泄露”。

按KEY_UP按键,可以切换当前操作内存(内部内存/外部内存),KEY1键用于更新p的内容,更新后的内容将重新显示在LCD模块上面。

本章,我们还可以借助USMART,测试内存的分配和释放,有兴趣的朋友可以动手试试。如右图USMART测试内存管理函数所示。

/////////////////////////插补:printf和sprintf函数的用法////////////////////////////

printf和sprintf函数的用法非常重要,用于程序参数调试。这两个函数都包含在系统启动代码“stdio.h”头文件中;

1,例:printf("Memory Malloc Test%03d",i);//将“Memory Malloc Test”用串口输出,利用串口助手可以看到输出的结果;

"03"表示参数“i”的值只显示3位,%d-输出控制符;d-将“i”以十进制的形式输出;i的范围0--255(因为是u8类型);输出参数可以是多个,可以参考郝斌老师的相关视频;输出控制符包含:%Ld--L代表long类型;%c--代表字符类型;:%X--代表16进制并大写;%s-字符串类型

2,如何理解字符串打印函数int sprintf(char * __restrict /*s*/, const char * __restrict /*format*/, ...) __attribute__((__nonnull__(1,2)));?

在内存管理实验中例如,sprintf((char*)p,"Memory Malloc Test%03d",i)函数的使用问题:

1),第一个形参(char*)p的意思是(第一个形参必须是指针类型),第二个形参即字符串“Memory Malloc Test%03d”存储在内存中的具体指针值,因为字符串是u8类型即char*类型,所以“(char*)p”与之呼应;因为第二个形参“Memory Malloc Test%03d”中有输出控制符“%03d”,所以第一个形参(char*)p的值是变化的(因为参数“i”的值在变);这里输出控制符“%03d”的意思可以参考printf()函数;

也就是说,sprintf函数的第一个形参必须是指针类型,它是第二个形参(输出内容)在存储器中存储的首地

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top