C中的双重函数间接

时间:2015-12-17 13:32:09

标签: c function-pointers cortex-m

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

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

我想做的是:

  • 启动时保存所有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();
}

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

4 个答案:

答案 0 :(得分:3)

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

尝试使用(*x_IRQ_addr)();代替*x_IRQ_addr();

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

答案 1 :(得分:0)

致电

x_IRQ_addr();

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

答案 2 :(得分:0)

提示使用(*x_IRQ_addr)();*x_IRQ_addr();工作; 但是,有一个关于为其分配地址的问题。 实际上,为了保存x_IRQ_addr的地址,我应该已经完成​​了

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

而不是

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

但我的问题可能不够清楚

答案 3 :(得分:0)

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

使用'复制'作为链接器命令文件元素之一到正确的位置。

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

通常,这意味着启动代码将跳转(完成加载后)到“开始”。目标代码中的代码位置。

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