ARM芯片STM32出現HardFault Handler硬件中斷通常有兩種狀況:html
此次遇到的問題是棧空間不夠。程序員
##ARM程序的組成[1]## 在Keil4的Build Out窗口中有下列的調試信息: 數組
那麼其中的Program Size: Code=12384 RO-data=420 RW-data=52 ZI-data=37044 分別表明什麼意義呢?數據結構
此處所說的「ARM程序」是指在ARM系統中正在執行的程序(在RAM中的程序)。函數
一個ARM程序包含3部分:RO,RW和ZI。RO是程序中的指令和常量;RW是程序中的已初始化變量;ZI是程序中的未初始化的變量.由以上3點說明能夠理解爲:RO就是readonly,RW就是read/write,ZI就是zero。post
##堆和棧的區別##ui
當我把幾個全局的數組長度double BUFER[sample_num]都調到10000+時,Keil會出現報錯。 操作系統
BSS指用來存放程序中未初始化的全局變量的一塊內存區域,顯然這個BUFFER數組存在全局區,而ROM內存不夠致使出錯。.net
舉個「栗子」說明一下這幾個區的不一樣:調試
<!-- lang: cpp --> int aa=0; //全局(初始化)區 int bb; //全局(未初始化)區 void main() { int b; //棧 char s[]="abc"; //棧 char *p= "LZU"; //在文字常量區 static int c =0 ; //靜態初始化區 p1= (char *)malloc(10); //堆區 strcpy(p,"LZU"); //"LZU"放在常量區 }
##遇到問題## 在main中有這樣幾個函數:
<!-- lang: cpp --> filter(ReceiveData,BUFER,sample_num); butter_high(BUFER,HighOut,sample_num); butter_low(HighOut,LowOut,sample_num); DIFF(&LowOut[0],BUFER,sample_num);
用來濾波和差分,然而繼續在後面加上一行cnt=find_max(BUFER,peak,sample_num)時會跳入到HardFault Handler中。跟蹤發現,它影響整個程序的方式還特別奇怪,不加入它的時候ADC能採樣sample_num個數據。加入它時,ADC在沒采夠sample_num個數據時就會跳入到HardFault Handler中。這樣讓我一直覺得是ADC採樣致使的硬件錯誤中斷。
##解決問題## 仔細看一下cnt=find_max(BUFER,peak,sample_num)的代碼
<!-- lang: cpp --> int find_max(double* in,int* out,int length) { int i,j; double Max,Min,Temp=0; int WaveStart[1000]; int MaxPoint[1000]; }
發現它定義了兩個很大的局部變量數組,而局部變量是存在棧中的,1000+1000大於開始定義的1024個字節。因此出現了硬件中斷錯誤。
由於在程序中沒有動態分配內存,能夠在startup文件中把Heap_size定義爲0.
##Keil輸出的MAP文件##
__initial_sp 0x20016c68 Data 0 startup_stm32f2xx.o(STACK)
STACK 0x20014868 Section 9216 startup_stm32f2xx.o(STACK)
說明stack大小爲0x2400
##Reference##
[1].http://blog.csdn.net/jamestaosh/article/details/4348385