C中的双重函数间接

我正在为ARM Cortex-M0 CPU编写一个bootloader。 我需要将IRQ转发到目标应用程序,遗憾的是,此CPU中的IRQ向量位于固定地址,我无法重新定位,所以我需要一些技巧。

我知道目标应用程序的IRQ的地址存储的地址。 所以,假设在地址0x5008处有void x_IRQHandler(void)的地址(目标app)

我想做的是:

  • 在启动时保存所有x_IRQHandler()的地址(以便它不在运行时计算);
  • 每当引导加载程序收到IRQ调用时,从其地址调用目标应用程序中的相关IRQ函数。

这是我在bootloader中所做的,我找不到合适的语法。

//pointers to x_IRQHandler() functions void(* x_IRQ_addr)(void); x_IRQ_addr = (void(*)(void))(0x5008); //here I should call the function pointed by x_IRQ_addr; but this syntax is not valid void x_IRQ_Handler(void) { *x_IRQ_addr(); } 

我尝试了不同的方法但没有成功,我该如何解决?

函数调用operator ()优先级高于间接运算符*

尝试使用(*x_IRQ_addr)(); 而不是*x_IRQ_addr();

你也可以把它写成x_IRQ_addr(); 因为*x_IRQ_addr是一个函数指示符,它将转换为指向()运算符操作数的函数的指针,因此取消引用会浪费。

打电话吧

 x_IRQ_addr(); 

不需要**x_IRQ_addr()意味着您要取消引用该函数返回的值(该值无效且无论如何都不返回任何内容)。

提示使用(*x_IRQ_addr)();*x_IRQ_addr(); 工作; 但是,为其分配地址还有另一个问题。 的确,为了保存x_IRQ_addr的地址,我应该这样做

 x_IRQ_addr = *(void(**)(void))(0x5008); 

代替

 x_IRQ_addr = (void(*)(void))(0x5008); 

但我的问题可能不够明确

解决潜在问题的常用方法是让链接器命令文件将中断向量数组放在目标程序中的不同位置,

将’copy’用作正确的位置作为链接器命令文件元素之一。

然后,在启动之前,目标代码在进入’main()’之前将中断向量数组复制到正确的位置,覆盖引导代码中断向量数组。

通常,这意味着引导代码将跳转(完成加载后)到目标代码中的“start.s”代码位置。

您编写/链接自定义start.s文件,该文件执行所需的中断向量数组副本到正确的位置