Return "function pointer mode" 中函数的值
Return value from function in "function pointer mode"
首先,对不起我的英语。我是巴西人,仍在努力学习(英语和编程)。
我正在尝试创建一个固件应用程序(STM32 uc),它可以访问其他固件(我的地址分为 BL + FWA + FWB),但我有一个问题,找不到原因。
FWB 需要访问 FWA 上的功能,以使用更少的闪存区域。
我可以访问函数本身,在其中执行任何操作,但是当达到 return 时,它会给我一个 HardFault。
我正在使用分散文件来使用 FWA 和 B 上共享的内存。
LR_IROM1 0x08004000 0x00004000 { ; load region size_region
ER_IROM1 0x08004000 0x00004000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 UNINIT 0x00001000 { ; No init data
*(.noinit)
}
RW_IRAM2 0x20001000 0x00004000 {
.ANY (+RW +ZI) //RW data
}
}
我的函数定义为
uint getInt(void) __attribute__((section(".ARM.__at_0x8006000")));//My fw was at 0x4000, total size is 0x4000,
//so space is not the problem.
uint getInt(void){
return 42;
}
在我的申请中(运行 在 FWA 上进行自我测试,但没有结果),我试图这样称呼它:
uint (*fun_ptr)(void) = (uint(*)(void))0x8006000;
uint _get_int= fun_ptr();
uint result = _get_int();
编辑:
使用时
IntFunc p = getInt;
uint ccccc = p();
uint aaaa = getInt();
所有选项都工作正常,问题是在使用地址时。
正如我提到的,我可以进入函数“getInt()”,我可以在其中执行任何代码指令,但是当到达“return 42”时,我有一个硬故障。
我找到了另一种方法来做到这一点,使用结构,工作,但我认为理解这个问题非常重要,理解错误在哪里,这有助于不再犯错误。
编辑 2:
我想了解问题,而不仅仅是简单地获得解决方案。
这种方法对我有用:
main.h 文件
typedef struct bootloaderApi bootloaderApi;
typedef unsigned int (*do_something_t)(void);
struct bootloaderApi{
do_something_t do_something;
};
和Main.c:
const struct bootloaderApi api __attribute__((section(".ARM.__at_0x8005000")))
= {.do_something = &getInt}; //address 0x5000 to test.
并将其用作
struct bootloaderApi *apit = (struct bootloaderApi *)0x8005000;
uint pa = api.do_something();
它工作正常,pa return给我 uint 42。
谢谢。
尝试:
uint (*fun_ptr)(void) = (uint(*)(void))0x8006001;
因为这个架构上的所有函数指针都必须是奇数。
地址是第一条指令(总是偶数)的实际地址加一。最后一位表示该指令使用“thumb”指令集,而不是“arm”指令集,该指令集在此设备上不可用。
首先,对不起我的英语。我是巴西人,仍在努力学习(英语和编程)。
我正在尝试创建一个固件应用程序(STM32 uc),它可以访问其他固件(我的地址分为 BL + FWA + FWB),但我有一个问题,找不到原因。 FWB 需要访问 FWA 上的功能,以使用更少的闪存区域。 我可以访问函数本身,在其中执行任何操作,但是当达到 return 时,它会给我一个 HardFault。 我正在使用分散文件来使用 FWA 和 B 上共享的内存。
LR_IROM1 0x08004000 0x00004000 { ; load region size_region
ER_IROM1 0x08004000 0x00004000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 UNINIT 0x00001000 { ; No init data
*(.noinit)
}
RW_IRAM2 0x20001000 0x00004000 {
.ANY (+RW +ZI) //RW data
}
}
我的函数定义为
uint getInt(void) __attribute__((section(".ARM.__at_0x8006000")));//My fw was at 0x4000, total size is 0x4000,
//so space is not the problem.
uint getInt(void){
return 42;
}
在我的申请中(运行 在 FWA 上进行自我测试,但没有结果),我试图这样称呼它:
uint (*fun_ptr)(void) = (uint(*)(void))0x8006000;
uint _get_int= fun_ptr();
uint result = _get_int();
编辑: 使用时
IntFunc p = getInt;
uint ccccc = p();
uint aaaa = getInt();
所有选项都工作正常,问题是在使用地址时。
正如我提到的,我可以进入函数“getInt()”,我可以在其中执行任何代码指令,但是当到达“return 42”时,我有一个硬故障。
我找到了另一种方法来做到这一点,使用结构,工作,但我认为理解这个问题非常重要,理解错误在哪里,这有助于不再犯错误。
编辑 2: 我想了解问题,而不仅仅是简单地获得解决方案。 这种方法对我有用: main.h 文件
typedef struct bootloaderApi bootloaderApi;
typedef unsigned int (*do_something_t)(void);
struct bootloaderApi{
do_something_t do_something;
};
和Main.c:
const struct bootloaderApi api __attribute__((section(".ARM.__at_0x8005000")))
= {.do_something = &getInt}; //address 0x5000 to test.
并将其用作
struct bootloaderApi *apit = (struct bootloaderApi *)0x8005000;
uint pa = api.do_something();
它工作正常,pa return给我 uint 42。
谢谢。
尝试:
uint (*fun_ptr)(void) = (uint(*)(void))0x8006001;
因为这个架构上的所有函数指针都必须是奇数。
地址是第一条指令(总是偶数)的实际地址加一。最后一位表示该指令使用“thumb”指令集,而不是“arm”指令集,该指令集在此设备上不可用。