您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

时间:2020-12-28 11:02:23  来源:  作者:

1、编译失败时

很多人从事嵌入式单片机开发,不怎么关心内存分配问题。尤其是现在STM32大行其道之时,型号众多,可选择性大,而且RAM也是极大的增加,不像开发51单片机那样要仅仅盯着RAM的分配及使用情况。对于简单的项目应用,功能单一的情况下,不用过于操心RAM的使用情况。随着功能的增多,模块增多之后,尤其编译时提示内存不足之时,如下图所示

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

内存RAM不足编译失败

发生这种情况,就要左看看右看看,这边减少一些那边减少一些,或者做刚做的改动调整一下,做出妥协的做法了。

2、弄清RAM使用情况

作为一个认真执着的开发工程师(码农)对于RAM的使用情况是否需要弄清它呢?怎么样弄清它呢?有没有一个方法可以让程序自动告诉我们RAM用来多少?还剩余多少呢?答案是有的。

2.1、RAM结构

RAM结构很简单,如下图所示。

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

已STM32F103RB为例

在实践中,变量得需要时动态增加或者减少的,因此上述分区基本不变,变化的是具体区域的地址;我们只要拿捏住芯片RAM大小与堆栈区的大小及栈定的地址就可以很方便地知道其他区域的使用情况了。那么我们怎么知道栈顶地址呢?做过STM32应用编程(IAP)的朋友应该很容易想到,它就保存在0x08000000地址处(对此不清楚的朋友可以查下相关资料)。题外话:系统是怎么知道堆栈(上图红线)越界了呢?知道的朋友可以留言告诉我一下,谢谢。

2.2、验证栈顶地址

验证栈顶地址的方法有3种,

第一是看项目的map文件,如下图所示。

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

map文件查找栈顶地址

第二是仿真看MSP寄存器,如下图所示。

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

软件仿真查看MSP,仅启动仿真功能不运行

第三种是查看BIN文件的第一个字,如下图所示。

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

生成工程BIN文件查看第一个字,这是IAP功能的基础

通过上面三中方法验证了栈顶地址是一致的。但是这些我能只能人工去做,现在就让软件自动告诉我们RAM分配清单。

3、让软件自动输出RAM分配清单

关键点:一是,到.s文件查看堆与栈分配的大小,定义如下图所示。

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

定义芯片RAM内存相关信息

当更改S文件中的堆栈配置时这里的宏定义也要跟着改变(要是有知道在C文件中引用S文件定义的朋友请留言告诉作者,谢谢)。

下面简单地写一个测试公共变量得函数,测试堆内存得函数,同时实现写一个输出RAM分配清单函数,如下:

#define App_START_ADDRESS 		0x08000000			//开始地址(栈顶地址)
#define RAM_START_ADDRESS 		0x20000000			//RAM开始地址
#define APP_STACK_SIZE			0x1000				//栈大小(字节数量)4KB
#define APP_HEAP_SIZE			0x1000				//堆大小(字节数量)4KB
#define MCU_RAM_SIZE			0x5000				//20KB
// --------------------------------------------------
#define BUFF_SIZE				1024				//定义公共大小	
char buff[BUFF_SIZE];								//定义公共变量
int GetGloablVarSum(void)
{
	int i,sum=0;									//局部变量
	for(i=0;i<BUFF_SIZE;i++)						//公共变量初始化		
	{
		buff[i]=i;
		sum+=buff[i];								//计算功能变量的和
	}
	return sum;										//返回计算和		
}
// --------------------------------------------------
int GetHeapVarSum(void)
{
	int i,sum=0;									//定义公共变量
	char *p1,*p2=(char*)malloc(BUFF_SIZE);			//从堆区申请内存
	p1=p2;
	memcpy(p2,buff,BUFF_SIZE);						//将公共变量的值拷贝到申请的内存中		
	p1=p2;
	for(i=0;i<BUFF_SIZE;i++)						//计算申请内存中值的和		
	{
		sum+=*p2++;
	}
	return sum;										//返回计算和
}
// --------------------------------------------------
void TellAboutRam()
{
	unsigned int StackTopAddr=(*(__IO u32*)APP_START_ADDRESS);				//获取栈顶地址
	unsigned int HeapTopAddr=StackTopAddr-APP_STACK_SIZE;					//获取堆顶/栈底地址
	unsigned int GlobalVarSize=HeapTopAddr-APP_HEAP_SIZE-RAM_START_ADDRESS;	//计算公共变量区域大小
	unsigned int RamFreeSize=MCU_RAM_SIZE-(StackTopAddr-RAM_START_ADDRESS);	//计算空闲区大小
	printf ("栈	顶t=t%08XH n",StackTopAddr); 
	printf ("堆	顶t=t%08XH n",HeapTopAddr); 
	printf ("未分配区t=t%d Byten",RamFreeSize);
	printf ("栈	区t=t%d Byten",APP_STACK_SIZE);
	printf ("堆	区t=t%d Byten",APP_HEAP_SIZE);
	printf ("公共变量区t=t%0d Byten",GlobalVarSize);
}
// --------------------------------------------------
int main (void)  
{              
	SER_Init ();                  
	printf ("------------- Hello World ------------n");      
	printf ("测试公共变量t=t%d tn",GetGloablVarSum());      
	printf ("测	堆区t=t%d tn",GetHeapVarSum()); 
	TellAboutRam();	
	while (1) 
	{                   
    ; 
	}                           
}

仿真输出如下图所示:

从事开发多年,分不清STM32的RAM使用情况?一图弄清它

 

总之弄清RAM分配情况很简单,首先抓住栈地址特别是0x08000000这个地址得值,其次是弄清S文件中堆与栈的大小。还有什么好方法欢迎留言。



Tags:STM32   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
工欲善其事,必先利其器。STM32Cube生态系统是ST为STM32开发者打造的软件生态,是嵌入式开发的利器。为提升功能丰富且高能效的STM32系列微控制器的易用性,2019年,意法半导体在STM...【详细内容】
2021-01-22  Tags: STM32  点击:(199)  评论:(0)  加入收藏
1、编译失败时很多人从事嵌入式单片机开发,不怎么关心内存分配问题。尤其是现在STM32大行其道之时,型号众多,可选择性大,而且RAM也是极大的增加,不像开发51单片机那样要仅仅盯着R...【详细内容】
2020-12-28  Tags: STM32  点击:(317)  评论:(0)  加入收藏
最近,几部优秀悬疑剧的上线,大家打招呼的方式有了新梗:“嗨!一起爬山吗?” 黑客们对“暗黑手段”的力争上游,谁也不能阻止。比如,近日以色列的研究团队公开了一项窃听技术,选中了随...【详细内容】
2020-07-16  Tags: STM32  点击:(95)  评论:(0)  加入收藏
01话 题经常有大学生同学纠结:我到底是学STM32还是学嵌入式linux。这个问题很多人都会有自己的看法,今天我试着从多个角度,把我了解到的事实讲一下,希望对大家有所启发。02STM...【详细内容】
2020-06-17  Tags: STM32  点击:(80)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的&emsp;&emsp;程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条