亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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文件中堆與棧的大小。還有什么好方法歡迎留言。

分享到:
標簽:STM32
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定