在分支到Cortex-M0上的函数指针时的UsageFault

时间:2016-10-15 09:00:36

标签: pointers gcc arm cortex-m thumb

我在STM32F0(ARM Cortex-M0)上运行代码。我定义了一个指向nested function的函数指针:

void My_Async_Func(void *handle, void (*complete)(bool success)) {
    /* 
     *  \/ A nested function \/
     */
    void receiveHandler(void) {
        // This function lies at an even-numbered address
    }
    /* ... */
    uart->rxDoneHandler = &receiveHandler;
    Go(uart);
}

嵌套功能似乎搞砸了。稍后当我调用rxDoneHandler指针时,它会尝试转移到0x8c0c6c0c并获得UsageFault。根据{{​​3}},这是因为我在仅支持Thumb指令集的处理器上分支到偶数地址,这要求您只分支到< em>奇数地址。

我使用的是GCC arm-none-eabi 4.9.3。我的CFLAGS是:

arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -O0 -g3 -Wall -fmessage-length=0 -ffunction-sections -c -MMD -MP 

我尝试过的事情

我尝试使用-mthumb-interwork按照建议ARM docs调用gcc。结果相同。

我尝试使用类似

的属性手动设置功能的对齐方式
__attribute__((aligned(16))) void receiveHandler(void) {

}

结果相同。

当我把它称为

时,我尝试手动向指针添加1
(uart->rxDoneHandler + 1)();

结果相同。

我做错了什么,或者这是编译器中的错误?

1 个答案:

答案 0 :(得分:1)

嵌套函数必须不能从封闭函数的外部调用,除非你仍然“逻辑”地在函数内部;从嵌套函数的GCC页面(强调我的):

  

可以通过存储地址或将地址传递给另一个函数来从名称范围之外调用嵌套函数:

 hack (int *array, int size)
 {
   void store (int index, int value)
     { array[index] = value; }

   intermediate (store, size);
 }
     

这里,函数intermediate接收store的地址作为参数。如果存储中间调用,则赋予store的参数用于存储到数组中。 但是只要包含函数(在本例中为hack)不退出,此技术才有效。

我的猜测是你注册uart->rxDoneHandler作为中断服务例程(或从ISR中调用的东西)。你不能这样做。