当前位置: 代码迷 >> 单片机 >> STM32F407通过地址直接调用函数进入HardFault_Handler的有关问题
  详细解决方案

STM32F407通过地址直接调用函数进入HardFault_Handler的有关问题

热度:321   发布时间:2016-04-28 14:45:30.0
STM32F407通过地址直接调用函数进入HardFault_Handler的问题
各位大神好!
我通过自定义scatter文件将set_LED这个函数固定到了0x080E0020这个地址。
set_LED函数的申明:
void set_LED(int LEDn, int state) __attribute__((section(".ARM.__at_0x080E0020")));

现在我在main函数中这样调用:
#include "stm32f407xx.h"

const int temp __attribute__((section(".ARM.__at_0x08080020"))) = 12;

int main()
{
if(temp==12){
//GPIOF->BSRRH |= 1<<6;
((void (*)(int, int))0x080E0020)(0,1);
}
while(1){
}
}

在调试状态,可以看到是进入了set_LED这个函数的,但是再进行下去就直接HardFault_Handler了。
求告知真相。
------解决思路----------------------
引用:
Quote: 引用:

Quote: 引用:

这是我在调试状态在HardFault_Handler中加上一个while(1),并在此处设上断点时call stack+local这一项的截图,想看看在程序临死之前到底干了什么,果然我觉得没有什么异常啊

这快成我的调试贴了。
换个马甲继续调。


很有可能是硬件操作有问题,比如说,在使用该GPIO前,没有使能,没有配置时钟,没有配置方向,等等。直接使用该IO,而没有做初始化,是造成这类问题的最常见原因。LZ你是不是中招了

在阿莫上开了一贴,有人回答了,就是set_LED这个函数的地址并不是链接到0x080E0020,而是链接到0x080E0021这个地方的,我在map文件里面也看到了
 set_LED                                  0x080e0001   Thumb Code    34  systeminit.o(.ARM.__at_0x080E0000)


给CPU执行的地址是0x080E0021,但在内存中其实还是0x080E0020,LZ,你注意ARM的Thumb指令集要求,在地址位的最低比特位是1,表示是Thumb的,0表示ARM的。

这是从ARM7时代开始,也即是ARMv4版本的汇编指令体系结构就开始了,现在上到ARMv6/v7,或者说CM0/3,因为历史原因,地址位的最后一个bit还是1,v6版本开始,就是Thumb2指令了,没有ARM指令,LZ以后在调试代码时,多注意看看汇编窗口,可以发现这个现象的。此外,可以看看CM3权威指南这本书,讲得很好很清楚。
  相关解决方案