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