詳解STM32單片機(jī)的堆棧
- 棧區(qū)(stack)
- 堆區(qū)(Heap)
- 全局區(qū)(static)
- 文字常亮區(qū)程序代碼區(qū)
????棧是從高到低分配,堆是從低到高分配。
普通單片機(jī)與STM32單片機(jī)中堆棧的區(qū)別
????普通單片機(jī)啟動(dòng)時(shí),不需要用bootloader將代碼從ROM搬移到RAM。????但是STM32單片機(jī)需要,可以參考相關(guān)文章:STM32代碼的啟動(dòng)過(guò)程。這里我們可以先看看單片機(jī)程序執(zhí)行的過(guò)程,單片機(jī)執(zhí)行分三個(gè)步驟:
- 取指令
- 分析指令
- 執(zhí)行指令
- 這些存儲(chǔ)單元中的內(nèi)容都是程序執(zhí)行過(guò)程中被中斷打斷時(shí),事故現(xiàn)場(chǎng)的一些相關(guān)參數(shù)。如果不保存這些參數(shù),單片機(jī)執(zhí)行完中斷函數(shù)后就無(wú)法回到主程序繼續(xù)執(zhí)行了。
- 這些存儲(chǔ)單元的地址被記在了一個(gè)叫做堆棧指針(SP)的地方。
結(jié)合STM32的開(kāi)發(fā)講述堆棧
????從上面的描述可以看得出來(lái),在代碼中是如何占用堆和棧的??赡芎芏嗳诉€是無(wú)法理解,這里再結(jié)合STM32的開(kāi)發(fā)過(guò)程中與堆棧相關(guān)的內(nèi)容來(lái)進(jìn)行講述。???如何設(shè)置STM32的堆棧大小?????在基于MDK的啟動(dòng)文件開(kāi)始,有一段匯編代碼是分配堆棧大小的。????這里重點(diǎn)知道堆棧數(shù)值大小就行。還有一段AREA(區(qū)域),表示分配一段堆棧數(shù)據(jù)段。數(shù)值大小可以自己修改,也可以使用STM32CubeMX數(shù)值大小配置,如下圖所示。
????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é)的??臻g。所以,在函數(shù)內(nèi)有較多局部變量時(shí),就需要注意是否超過(guò)我們配置的堆棧大小。????函數(shù)參數(shù):void?HAL_GPIO_Init(GPIO_TypeDef?*GPIOx,?GPIO_InitTypeDef *GPIO_Init)
????這里要強(qiáng)調(diào)一點(diǎn):傳遞指針只占4字節(jié),如果傳遞的是結(jié)構(gòu)體,就會(huì)占用結(jié)構(gòu)大小空間。提示:在函數(shù)嵌套,遞歸時(shí),系統(tǒng)仍會(huì)占用??臻g。????堆(Heap)的默認(rèn)設(shè)置0x200(512)字節(jié)。Heap_Size EQU 0x200
????大部分人應(yīng)該很少使用malloc來(lái)分配堆空間。雖然堆上的數(shù)據(jù)只要程序員不釋放空間就可以一直訪問(wèn),但是,如果忘記了釋放堆內(nèi)存,那么將會(huì)造成內(nèi)存泄漏,甚至致命的潛在錯(cuò)誤。MDK中RAM占用大小分析
????經(jīng)常在線調(diào)試的人,可能會(huì)分析一些底層的內(nèi)容。這里結(jié)合MDK-ARM來(lái)分析一下RAM占用大小的問(wèn)題。在MDK編譯之后,會(huì)有一段RAM大小信息:????這里4 6=1640,轉(zhuǎn)換成16進(jìn)制就是0x668,在進(jìn)行在調(diào)試時(shí),會(huì)出現(xiàn):
????這個(gè)MSP就是主堆棧指針,一般我們復(fù)位之后指向的位置,復(fù)位指向的其實(shí)是棧頂:
???而MSP指向地址0x20000668是0x20000000偏移0x668而得來(lái)。具體哪些地方占用了RAM,可以參看map文件中【Image Symbol Table】處的內(nèi)容:
END
來(lái)源:網(wǎng)絡(luò)版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除。
▍