STM32的堆棧大小在官方文件已經定義好了,分別是:
Heap_Size EQU 0x00000200 一共512字節
Stack_Size EQU 0x00000400 一共1K字節
/*********************************************************************************************/
可是STM32在keil環境下每次編譯後的堆棧起始地址並非固定的(就算事先已經定義好了堆棧的大小),由於棧的起始地址是由用戶程序中事先定義好的變量數目決定的(實測是如此)。但欣慰的是,一旦此次編譯以後,堆棧的首地址就不會再發生改變了,換言之,就是在燒完程序以後,堆棧的地址就永遠不變了。
/*********************************************************************************************/
要關心STM32的堆棧關係,首先沒法避免的就是下面這兩幅圖片了:
html
圖一:MDK環境下,STM32 Bulid Output窗口部分截圖
圖二:MDK環境下,STM32的.map文件中關於堆棧地址的說明(綠色高亮部位)
/*********************************************************************************************/
STM32的內部sram的首地址爲0x20000000,圖二中的__initial_sp既爲棧的高地址(也就是棧的首地址)(STM32的堆棧地址在MDK下的配置默認是連續的,棧的地址高於堆的地址,棧的生長方向爲從高地址向低地址生長,棧的地址爲從低地址向高地址生長,最後二者生長到了一塊兒,也就是「頭碰頭」)圖二中的HEAP既爲堆的低地址,STACK既爲最後頭碰頭的地址(注意並非棧的起始地址而是結束地址,由於棧相對於堆是逆向生長的)
/*********************************************************************************************/
那麼問題來了,__initial_sp的值是怎麼來的呢?這就要看圖一了。
首先拋出結論:__initial_sp = 0x20000000+RW+ZI
RW:Read/Write 可讀可寫的數據段。就是那些在任務初始化時就已經被賦值了的變量,MDK通常將這種類型的數據保存在STM32的SRAM中。(「全局變量」存在「普通意義上的」SRAM 中)(「局部變量」存儲在「棧」中)(「局部的static變量」在存儲上等價於全局變量)
ZI:Zero Initial 初始化爲0的變量,也就是直接初始化並無賦值的變量spa
能夠這麼認爲:在STM32的片內SRAM中,__initial_sp-0x20000000爲用戶已經使用了的SRAM空間,從高地址到低地址依次爲「棧Stack」「堆Heap」「全局變量」
/*********************************************************************************************/
至此,圖二中綠色高亮部分的STACK和HEAP的數值也就不難理解了
STACK = __initial_sp - 0x400(棧的大小)
HEAP = STACK - 0x200(堆的大小)
/*********************************************************************************************/.net
下面的百度文庫給出了比較完整的答案:(百度文庫此次居然靠譜了word天)
https://wenku.baidu.com/view/f13602e403d8ce2f016623a0.html
————————————————
版權聲明:本文爲CSDN博主「ryzejiang」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/qq_15210067/article/details/766515093d