FreeRTOS是如何工作的--GCC Naked属性

GCC Naked 属性

前一节讲述了如何在C中用 signal属性来写一个ISR.,以及它是如何使 执行上下文自动保存的(只有那些被ISR修改过的处理器寄存器才会得到保存)。然而,执行一个上下文切换需要保存完整的上下文。

应用程序代码能够 在进入ISR时,明确(explicitly)地 保存所有寄存器,但是这样会使 某些处理器寄存器 保存两次---一次是由编译器生成的代码,另一次是由应用程序自己。这不是我们所需要的,可以在'signal'属性后 添加 'naked'属性来避免:

void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
void SIG_OUTPUT_COMPARE1A( void )
{
    /* ISR C code for RTOS tick. */
    vPortYieldFromTick();
}

 'naked'属性阻止编译器生成任何函数入口或退出代码。现在变异这段代码,会得到更少的编译器输出:

;void SIG_OUTPUT_COMPARE1A( void )
;{
    ; ---------------------------------------
    ; NO COMPILER GENERATED CODE HERE TO SAVE
    ; THE REGISTERS THAT GET ALTERED BY THE
    ; ISR.
    ; ---------------------------------------
    ; CODE GENERATED BY THE COMPILER FROM THE
    ; APPLICATION C CODE.
    ;vTaskIncrementTick();
    CALL    0x0000029B       ;Call subroutine
    ; ---------------------------------------
    ; NO COMPILER GENERATED CODE HERE TO RESTORE
    ; THE REGISTERS OR RETURN FROM THE ISR.
    ; ---------------------------------------
;}


看看,入口 和 出口代码都没有了吧


使用 naked 属性,编译器不会生成任何入口和出口代码,所以必须明确(explicitly)加入。
portSAVE_CONTEXT()和portRESTORE_CONTEXT()这两个宏 是用来保存和恢复完整的
执行上下文的:

void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
void SIG_OUTPUT_COMPARE1A( void )
{
    /* Macro that explicitly saves the execution
    context. */
    portSAVE_CONTEXT();
    /* ISR C code for RTOS tick. */
    vPortYieldFromTick();
    /* Macro that explicitly restores the
    execution context. */
    portRESTORE_CONTEXT();
    /* The return from interrupt call must also
    be explicitly added. */
    asm volatile ( "reti" );
}


naked属性给了应用程序完整的控制权,在何时 ,怎么样保存AVR的上下文。如果应用程序代码在进入ISR前保存了完整的上下文,在执行上下文切换时不必再保存,所以不会有处理器的寄存器被保存两次。

===下一节: /html/2006-04/665.html===

作者:Gavin Lee   更新日期:2006-04-24
来源:upsdn.net   浏览次数:

相关文章

相关评论   发表评论