關注+星標公眾號,不錯過精彩內容

作者 | strongerHuang
微信公眾號 | strongerHuang
堆棧對于程序來說非常重要,程序能夠快速運行,堆棧起到非常大的作用,但你了解堆棧嗎?
概述
我們都知道堆棧位于RAM中,現在MCU的RAM相對較大(幾十上百K),所以分配的堆棧也是足夠大,很多人都不怎么關注這個堆棧的大小。
但是,以前MCU的RAM比較小,甚至1K都不到,所以,以前的工程師就比較關心堆棧的大小。
對于小項目而言,可能我們不用關心堆棧大小。
但是,如果項目大了,你就要注意了,你堆棧大小設置不合理,很有可能導致Fault。
想要知道堆棧有多大才合適,你就需要明白堆棧的作用,下面讓大家進一步了解堆棧。
關于堆棧
我們先看一下兩點經典的知識。
1.程序的內存分配
一個由C/C 編譯的程序占用的內存分為以下幾個部分:
棧區(stack):由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。
堆區(heap):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式類似于鏈表。
全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束后由系統釋放。
文字常量區:常量字符串就是放在這里的,程序結束后由系統釋放。
程序代碼區:存放函數體的二進制代碼。
2.經典例子程序
int?a =?0; ? ? ? ? ? ? ?//全局初始化區char *p1; ? ? ? ? ? ? ??//全局未初始化區main(){ ?int?b; ? ? ? ? ? ? ? ?//棧 ?char s[] =?"abc"; ? ??//棧 ?char *p2; ? ? ? ? ? ??//棧 ?char *p3 =?"123456"; ?//123456\0在常量區,p3在棧上。 ?static?int?c =0;//全局(靜態)初始化區 ?p1 = (char *)malloc(10); ?p2 = (char *)malloc(20); ??//分配得來得10和20字節的區域就在堆區。 ?strcpy(p1,?"123456"); ? ? ?//123456\0放在常量區,編譯器可能會將它與p3所指向的"123456"優化成一個地方。}單片機堆棧
從上面的描述可以看得出來,在代碼中是如何占用堆和棧的。
可能很多人還是無法理解,這里再結合STM32的開發過程中與堆棧相關的內容來進行講述。
1.如何設置STM32的堆棧大小?
這個問題在文章《STM32的啟動流程到底是怎樣的?》中講述了在MDK-ARM、IAR EWARM,以及使用STM32CubeMX設置堆棧大小的方法。
2.棧(Stack)
STM32F1默認設置值0x400,也就是1K大小。
Stack_Size? ? EQU ? ??0x400void?Fun(void){ ?char?i; ?int?Tmp[256]; ?//...}void?HAL_GPIO_Init(GPIO_TypeDef ?*GPIOx, GPIO_InitTypeDef *GPIO_Init)Heap_Size? ? ? EQU ? ??0x200結合Keil分析RAM占用大小




