I have a port.c file for FreeRTOS that throws an error message under AS7 indicating that a naked function can not support any statement types except ASM statements when a “naked” attribute is declared. Now lets make things a little more confusing … The same two functions will compile just fine under AS7 on a ATmega128A project I have, but not under a ATXmega128A project. Same AS7 program, same exact functions, but different processors. I don’t think it’s processor related myself. The code is below:
/*
* Manual context switch. The first thing we do is save the registers so we
* can use a naked attribute.
*/
void vPortYield( void ) __attribute__ ( ( naked ) );
void vPortYield( void )
{
portSAVE_CONTEXT();
vTaskSwitchContext();
portRESTORE_CONTEXT();
asm volatile ( "ret" );
}
/*-----------------------------------------------------------*/
/*
* Context switch function used by the tick. This must be identical to
* vPortYield() from the call to vTaskSwitchContext() onwards. The only
* difference from vPortYield() is the tick count is incremented as the
* call comes from the tick ISR.
*/
void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
void vPortYieldFromTick( void )
{
portSAVE_CONTEXT();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
portRESTORE_CONTEXT();
asm volatile ( "reti" );
}
/*-----------------------------------------------------------*/
AS7 is Atmel Studio 7 (Microchip Studio since the buyout). It uses GCC for the compiler, but I’m not sure what version. But it is pretty recent. I do not know the command to generate the error as it is part of the Studio 7 build process. The exact error message (two of them) is:
“(N) 2465:non-ASM statement in naked function is not supported” That’s all I have.
I had to look it up and found that several compilers do not allow to put C-statements in a functions which has the naked attribute. The reason is that it is considered not safe.
Now I wonder if it is allowed to call the C-function from within an inline statement:
Hein,
Yes I have 8 task toggling LEDs on an XMega128A1 part. Your suggestion was actually a very good one. Especially with what must be changes in GCC that caused this problem. I always include a Heartbeat LED that’s toggled from inside the ISR handler to let me know that the CPU is at least processing interrupts. But in order to do that, I placed an asm volatile (“hb_togl”); to a function called void hb_togl(void) that bumps a counter, checks if the counter has reached 1000, if yes, set the counter to zero and toggle the LED. That function is in C code, and the heartbeat LED toggles as well. I also looked at the .LSS listing to see if the asm statements were actually calling the required function, and they are. Another warm fuzzy feeling that it had a possibility of working. So it was a great learning experience.