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

UsageFault when branching to a function pointer on Cortex-M0

我 运行 在 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。根据 ARM docs,这是因为我在仅支持 Thumb 指令集的处理器上分支到 偶数 地址,这要求您仅分支到奇数 个地址。

我正在使用 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 调用 gcc。相同的结果。

我尝试使用

之类的属性手动设置函数的对齐方式
__attribute__((aligned(16))) void receiveHandler(void) {

}

同样的结果。

我试过在调用它时手动将指针加1

(uart->rxDoneHandler + 1)();

同样的结果。

是我做错了什么,还是编译器中的错误?

嵌套函数 必须 不能从封闭函数的外部调用,除非您仍然 "logically" 在该函数内;来自 GCC 嵌套函数页面(强调我的):

It is possible to call the nested function from outside the scope of its name by storing its address or passing the address to another function:

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

   intermediate (store, size);
 }

Here, the function intermediate receives the address of store as an argument. If intermediate calls store, the arguments given to store are used to store into array. But this technique works only so long as the containing function (hack, in this example) does not exit.

我的猜测是您将 uart->rxDoneHandler 注册为中断服务程序(或从 ISR 中调用的程序)。你不能那样做。