C 裸函数 - 在 1 个函数中执行汇编和 C 代码的灼热解决方案

C naked function - searing solution to execute both assembly and c code in 1 function

我想追踪 freertos isr 的。 freertos 使用 2 个 isr(irq 处理程序)裸函数。

id 喜欢在入门级和退出级进行如下跟踪调用(未注释)

#warning "system no longer operating with trace call since naked,.. solve"
void vPortSVCHandler( void )
{
  //hal_trace_wrapper_isr_enter(SVCall_IRQn); // modified

    __asm volatile (
                    "   ldr r3, pxCurrentTCBConst2      \n" /* Restore the context. */
                    "   ldr r1, [r3]                    \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
                    "   ldr r0, [r1]                    \n" /* The first item in pxCurrentTCB is the task top of stack. */
                    "   ldmia r0!, {r4-r11}             \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
                    "   msr psp, r0                     \n" /* Restore the task stack pointer. */
                    "   isb                             \n"
                    "   mov r0, #0                      \n"
                    "   msr basepri, r0                 \n"
                    "   orr r14, #0xd                   \n"
                    "   bx r14                          \n"
                    "                                   \n"
                    "   .align 4                        \n"
                    "pxCurrentTCBConst2: .word pxCurrentTCB             \n"
                );

  //hal_trace_wrapper_isr_exit(SVCall_IRQn); // modified
}

快速的想法是在自己的函数中提取裸露的部分。但随后堆栈指针将带有偏移量,我怀疑我完全破坏了系统。

是否有另一种解决方案可以在一个函数中同时执行 c 和 asm?

一些编译器支持使用 interrupt 属性生成 ISR。您可以尝试使用它来代替裸函数。

这个函数根本没有编译器生成的代码,只有你看到的汇编指令执行。所以这实际上不是 C 函数,而是汇编函数。确保在汇编指令执行之前绝对没有添加任何代码是赤裸裸的,因为 FreeRTOS kernel 必须完全控制堆栈和寄存器的使用方式。如果去掉naked属性,即使换成interrupt属性,代码也根本执行不了,肯定会崩溃。