The previous section showed how the 'signal' attribute can be used to write an ISR in C and how this results in
part of the execution context being automatically saved (only the processor registers modified by the ISR get saved).
Performing a context switch however requires the entire context to be saved.
The application code could explicitly save all the processor registers on entering the ISR, but doing so would result in some
processor registers being saved twice - once by the compiler generated code and then again by the application code. This is
undesirable and can be avoided by using the 'naked' attribute in addition to the 'signal' attribute.
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
void SIG_OUTPUT_COMPARE1A( void )
{
/* ISR C code for RTOS tick. */
vPortYieldFromTick();
}
The 'naked' attribute prevents the compiler generating any function entry or exit code. Now compiling the
code results in much simpler output:
;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.
; ---------------------------------------
;}
When the 'naked' attribute is used the compiler does not generate any function entry or exit code so this
must now be added explicitly. The RTOS macros portSAVE_CONTEXT() and portRESTORE_CONTEXT() respectively save and
restore the entire execution 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" );
}
The 'naked' attribute gives the application code complete control over when and how the AVR context is saved.
If the application code saves the entire context on entering the ISR there is no need to save it again before performing
a context switch so none of the processor registers get saved twice.
Next: RTOS Implementation - The FreeRTOS Tick Code
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|