gcc optimization return value handling
John Breitenbach
breiten@lexmark.com
Fri Jan 16 13:26:00 GMT 2009
rekisum@web.de wrote:
> Hi,
> I already put this in the FreeRTOS forum with no result so far:
>
> I got hit by a very strange GCC/FreeRTOS problem.
> In a task I check the return value of a function like this:
>
> int ret;
>
> if( xQueueReceive(QueueMain, &Event, portMAX_DELAY) == pdTRUE )
> {
> switch(Event.id)
> {
> case EV_KEY_MENU_OK:
> ret = menu_descend();
> if( ret != 0 )
> { . . . . .
> .
> .
> .
>
> Using this code the system hangs after returning from menu_descend()!
> The program gets stuck in xQueueReceive() in an endless loop of xTaskResumeAll().
> There is a while loop:
> while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL )
>
> As there is an portENTER_CRITICAL() in the beginning of that routine there
> interrupts are disabled, the os tick is no longer called.
>
>
> But, when I declare ret as volatile
> volatile int ret;
> the program runs as expected!
>
> Looking at the assembler code shows:
> Without volatile:
>
> bl menu_descend
> cmp r0, #0
> beq .L123
>
> With volatile:
>
> bl menu_descend
> str r0, [sp, #84]
> ldr r3, [sp, #84]
> cmp r3, #0
> beq .L123
>
> So it looks like that storing the return value on the stack
> and using r3 for comparison against zero saves my program
> from getting stuck.
>
> From here I only can guess.
> Maybe gcc tricks itself by the assumption that there lies a return value
> of the function on stack, but optimisation uses r0 for handover directly instead,
> and from there on the stack pointer is one position to low?
>
> Or has it to do with register treatment of freertos, especially register r0?
>
> I use freertos version 3.2 ( because thats what the project started with
> and I'm not allowed to upgrade ;-)
> It's a port for the STR7 ARM7 from ST.
> gcc is arm-elf-gcc 4.2.2
> optimization level is 2
>
> All that really frightens me!
> I must use optimization, at least for size, as the code got to big.
>
> What goes wrong here?
> __________________________________________________________________________
> Verschicken Sie SMS direkt vom Postfach aus - in alle deutschen und viele
> ausländische Netze zum gleichen Preis!
> https://produkte.web.de/webde_sms/sms
>
>
>
>
My guess is that you have an uninitialized variable somewhere [else],
and by making ret
a volatile, you just happen to see the desired results.
With what you've shown, r3 is now going to be 0 after your call, so is
the word at sp+84.
And perhaps, you'll see a different amount of stack space allocated in
this function -
all have the possibility of changing the "undefined" value of an
uninitialized variable.
More information about the Gcc-help
mailing list