學(xué)習(xí)STM32單片機(jī)的時(shí)候,總是能遇到“堆棧”這個(gè)概念。分享本文,希望對你理解堆棧有幫助。
對于了解一點(diǎn)匯編編程的人,就可以知道,堆棧是內(nèi)存中一段連續(xù)的存儲區(qū)域,用來保存一些臨時(shí)數(shù)據(jù)。堆棧操作由PUSH、POP兩條指令來完成。而程序內(nèi)存可以分為幾個(gè)區(qū):
棧區(qū)(stack)
堆區(qū)(Heap)
全局區(qū)(static)
文字常亮區(qū)程序代碼區(qū)
程序編譯之后,全局變量,靜態(tài)變量已經(jīng)分配好內(nèi)存空間,在函數(shù)運(yùn)行時(shí),程序需要為局部變量分配棧空間,當(dāng)中斷來時(shí),也需要將函數(shù)指針入棧,保護(hù)現(xiàn)場,以便于中斷處理完之后再回到之前執(zhí)行的函數(shù)。
棧是從高到低分配,堆是從低到高分配。
普通單片機(jī)與STM32單片機(jī)中堆棧的區(qū)別
普通單片機(jī)啟動時(shí),不需要用bootloader將代碼從ROM搬移到RAM。
但是STM32單片機(jī)需要。
這里我們可以先看看單片機(jī)程序執(zhí)行的過程,單片機(jī)執(zhí)行分三個(gè)步驟:
取執(zhí)行
分析指令
執(zhí)行指令
根據(jù)PC的值從程序存儲器讀出指令,送到指令寄存器。然后分析執(zhí)行執(zhí)行。這樣單片機(jī)就從內(nèi)部程序存儲器去代碼指令,從RAM存取相關(guān)數(shù)據(jù)。
RAM取數(shù)的速度是遠(yuǎn)高于ROM的,但是普通單片機(jī)因?yàn)楸旧磉\(yùn)行頻率不高,所以從ROM取指令慢并不影響。
而STM32的CPU運(yùn)行的頻率高,遠(yuǎn)大于從ROM讀寫的速度。所以需要用bootloader將代碼從ROM搬移到RAM。
使用棧就象我們?nèi)ワ堭^里吃飯,只管點(diǎn)菜(發(fā)出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準(zhǔn)備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。使用堆就象是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。
其實(shí)堆棧就是單片機(jī)中的一些存儲單元,這些存儲單元被指定保存一些特殊信息,比如地址(保護(hù)斷點(diǎn))和數(shù)據(jù)(保護(hù)現(xiàn)場)。
如果非要給他加幾個(gè)特點(diǎn)的話那就是:
這些存儲單元中的內(nèi)容都是程序執(zhí)行過程中被中斷打斷時(shí),事故現(xiàn)場的一些相關(guān)參數(shù)。如果不保存這些參數(shù),單片機(jī)執(zhí)行完中斷函數(shù)后就無法回到主程序繼續(xù)執(zhí)行了。
這些存儲單元的地址被記在了一個(gè)叫做堆棧指針(SP)的地方。
結(jié)合STM32的開發(fā)講述堆棧
從上面的描述可以看得出來,在代碼中是如何占用堆和棧的。可能很多人還是無法理解,這里再結(jié)合STM32的開發(fā)過程中與堆棧相關(guān)的內(nèi)容來進(jìn)行講述。
如何設(shè)置STM32的堆棧大小?
在基于MDK的啟動文件開始,有一段匯編代碼是分配堆棧大小的。
這里重點(diǎn)知道堆棧數(shù)值大小就行。還有一段AREA(區(qū)域),表示分配一段堆棧數(shù)據(jù)段。數(shù)值大小可以自己修改,也可以使用STM32CubeMX數(shù)值大小配置,如下圖所示。
在IAR中,是通過工程配置堆棧大小,如下圖所示。
STM32F1默認(rèn)設(shè)置值0x400,也就是1K大小。
Stack_Size EQU 0x400
?函數(shù)體內(nèi)局部變量:
void Fun(void){ char i; int Tmp[256]; //...}
局部變量總共占用了256*4 + 1字節(jié)的棧空間。所以,在函數(shù)內(nèi)有較多局部變量時(shí),就需要注意是否超過我們配置的堆棧大小。
函數(shù)參數(shù):
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
這里要強(qiáng)調(diào)一點(diǎn):傳遞指針只占4字節(jié),如果傳遞的是結(jié)構(gòu)體,就會占用結(jié)構(gòu)大小空間。提示:在函數(shù)嵌套,遞歸時(shí),系統(tǒng)仍會占用棧空間。
堆(Heap)的默認(rèn)設(shè)置0x200(512)字節(jié)。
Heap_Size EQU 0x200
大部分人應(yīng)該很少使用malloc來分配堆空間。雖然堆上的數(shù)據(jù)只要程序員不釋放空間就可以一直訪問,但是,如果忘記了釋放堆內(nèi)存,那么將會造成內(nèi)存泄漏,甚至致命的潛在錯誤。
MDK中RAM占用大小分析
經(jīng)常在線調(diào)試的人,可能會分析一些底層的內(nèi)容。這里結(jié)合MDK-ARM來分析一下RAM占用大小的問題。在MDK編譯之后,會有一段RAM大小信息:
這里4+6=1640,轉(zhuǎn)換成16進(jìn)制就是0x668,在進(jìn)行在調(diào)試時(shí),會出現(xiàn):
這個(gè)MSP就是主堆棧指針,一般我們復(fù)位之后指向的位置,復(fù)位執(zhí)向的其實(shí)是棧頂:
而MSP指向地址0x20000668是0x20000000偏移0x668而得來。具體哪些地方占用了RAM,可以參看map文件中【Image Symbol Table】處的內(nèi)容:
上一篇:Visual Studio 2019 +STM32實(shí)現(xiàn)串口通訊
下一篇:基于STM32的甲醛濃度檢測報(bào)警proteus仿真設(shè)計(jì)
推薦閱讀最新更新時(shí)間:2025-07-02 21:57





設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級數(shù)字信號控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- MC33174DR2G 有源高 Q 陷波濾波器的典型應(yīng)用
- 使用 Analog Devices 的 LTC1159CG-3.3 的參考設(shè)計(jì)
- LTC1727IS8-5、3.3V 和 5V 雙電源監(jiān)視器的典型應(yīng)用
- 使用 LT6202 將 ±10V 雙極性信號轉(zhuǎn)換為 0V 至 5V 輸入信號到 LTC2370CMS-16 的典型應(yīng)用
- LT3724 的典型應(yīng)用 - 高電壓、電流模式開關(guān)穩(wěn)壓控制器
- TS9010ACX5 RF 150mA, 1.5V CMOS LDO with Enable 典型應(yīng)用電路
- L5150GJ 5 V 低壓差穩(wěn)壓器的典型應(yīng)用
- MPC86XADS、XPC8xx 參考板,基于 XPC860EN MPU PowerQUICC MPC8xx 處理器
- OP249GSZ-REEL 失調(diào)調(diào)整的典型應(yīng)用電路,用于同相放大器配置
- 使用 Microchip Technology 的 MAX3221ECAE 的參考設(shè)計(jì)
- 上汽大眾:汽車網(wǎng)絡(luò)安全漏洞防護(hù)
- 恩智浦推出全新電池控制IC系列 助力新能源解決方案發(fā)展
- 全球首條GWh級新型固態(tài)電池生產(chǎn)線樣件下線
- 總投資455億元!三大動力電池項(xiàng)目齊刷進(jìn)度條
- 現(xiàn)代汽車韓國建氫燃料電池廠,2028年投產(chǎn)
- 6月融資一覽:智能汽車芯片、第三代半導(dǎo)體、機(jī)器人成資本焦點(diǎn)
- 艙駕一體“點(diǎn)燃”新戰(zhàn)事
- 汽車智能化2.0引爆「萬億蛋糕」,誰在改寫游戲規(guī)則?
- 2025研華智能系統(tǒng)產(chǎn)業(yè)伙伴峰會成功舉辦
- 意法半導(dǎo)體公布2025年第二季度財(cái)報(bào)和電話會議時(shí)間安排
- 關(guān)于如何單獨(dú)失能STM32 TIM通道的方法
- STM32的定時(shí)器--輸入捕捉模式
- 【STM32F103攻城筆記】輸入捕捉實(shí)戰(zhàn)
- STM32 Timer1 TIM1 中斷
- STM32F207 TIM1 比較輸出 輸出多路不同頻率
- 關(guān)于STM32的IAP與APP互相跳轉(zhuǎn)常見問題分析
- STM32IAP程序和APP相互跳轉(zhuǎn)卡死問題
- 比手環(huán)監(jiān)測更靈敏 新款睡眠質(zhì)量檢測儀長這樣
- STM32外部中斷方式按鍵操作(STM32_09)
- STM32的中斷優(yōu)先級和庫函數(shù)的 開、關(guān)總中斷