参考自:C语言中将绝对地址转换为函数指针以及跳转到内存指定位置处执行的技巧 (转) - FightingChen - 博客园 (cnblogs.com)
STM32F407通过地址直接调用函数进入HardFault_Handler的问题-CSDN社区
项目有ota的需求,并且把一部分的程序需要写在Bootloader中,应用程序一部分功能只能去调用Bootloader中的函数,因为是分开两部分程序,所以只能靠地址去调用函数,查了很多网上的资料,没有找到怎么跳转和定义地址一起配合说明的清晰的文章,参考了上面两个人的文章,总结一下,仅供参考。
指定函数地址 >>> __attribute__((section(".ARM.__AT_addr")));
我这里的Test函数就是指定地址在0x08004000
void Test(uint8_t *da) __attribute__((section(".ARM.__AT_0x08004000")));
void Test(uint8_t *da)
{
uint8_t i;
for(i=0;i<12;i++)
{
*da=i;
da++;
}
}
调用函数的方式参考自最上面的文章
void main()
{
void (* my_function)(uint8_t *da);
uint8_t test[12];
my_function =(void (*)())(0x08004001);
my_function(test);
}
需要注意的是,跳转的函数的地址不是最开始定义的 0x08004000!!!!
是0x08004001,我就是踩了这个坑,如果使用0x08004000去跳转,会有个奇怪的现象,我使用的是keil,用jlink进入调试,在 my_function(test); 处打断点,点击Step(单步进入),程序运行正常,test数组被赋值,点击Step Over的话就直接跳到HardFault_Handler中,只要是没有单步运行那个地方的程序就会跳到HardFault_Handler中,后面查阅了别人的提问后去看了一下map文件,发现是函数实际上是在0x08004001中,下面是测试程序中定义的函数地址:
map文件中的地址:
注意使用这个map文件中的地址就可以正常运行了