STM32跳入HardFault Handler中斷分析

ARM芯片STM32出現HardFault Handler硬件中斷通常有兩種狀況:html

  1. 訪問越界致使的Acess Violation或者內存溢出
  2. 堆棧溢出

此次遇到的問題是棧空間不夠。程序員

##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

  • 棧區(stack):由編譯器自動分配和釋放,存放函數的參數值局部變量的值等,其操做方式相似 於數據結構中的棧。
  • 堆區(heap):通常由程序員分配和釋放(malloc),若程序員不釋放,程序結束時可能由操做系統回收。分配 方式相似於數據結構中的鏈表。
  • 全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態 變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另外一塊區域。程序結束後由系 統自動釋放。
  • 文字常量區:常量字符串就是存放在這裏的。
  • 程序代碼區:存放函數體的二進制代碼。

當我把幾個全局的數組長度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

[2].http://www.mcuc.com.cn/thread-660-1-1.html

[3].http://www.openedv.com/posts/list/24152.htm

相關文章
相關標籤/搜索