FreeRTOS, idle hook and gcc

nobody wrote on Saturday, September 02, 2006:

hello,

Subject: optimalization

Problem:
OS works fine with -O1 -O2 -O3 and -Os but fails after 7-100 (during return from vApplicationIdleHook, when IDLE task is active, undefined instruction interrupt is generated) ticks with -O2 flag (without optimalization), when I set configUSE_IDLE_HOOK to 0 OS does not crash! why???

Hardware: AT91SAM7S256
Compiler: GCC 4.1.1 (WinARM 2006.06.06)
OS: FreeRTOS 4.1.0 (independent), configTOTAL_HEAP_SIZE = 24000

best rgs
Janusz

nobody wrote on Saturday, September 02, 2006:

void vApplicationIdleHook( void )       
{
       AT91C_BASE_PIOA->PIO_SODR = LED1;
}

code with -O1:

00109024 <vApplicationIdleHook>:
  109024:    2201          movs    r2, #1
  109026:    4b01          ldr    r3, [pc, #4]    (10902c <.text+0x102c>)
  109028:    631a          str    r2, [r3, #48]
  10902a:    4770          bx    lr

0010a850 <prvIdleTask>:
  10a850:    b5f0          push    {r4, r5, r6, r7, lr}
  10a852:    4e18          ldr    r6, [pc, #96]    (10a8b4 <.text+0x28b4>)
  10a854:    4f18          ldr    r7, [pc, #96]    (10a8b8 <.text+0x28b8>)
  10a856:    6833          ldr    r3, [r6, #0]
  10a858:    2b00          cmp    r3, #0
  10a85a:    d023          beq.n    10a8a4 <prvIdleTask+0x54>
  10a85c:    f7ff f9e8     bl    109c30 <vTaskSuspendAll>
  10a860:    683c          ldr    r4, [r7, #0]
  10a862:    f7ff ff29     bl    10a6b8 <xTaskResumeAll>
  10a866:    2c00          cmp    r4, #0
  10a868:    d01c          beq.n    10a8a4 <prvIdleTask+0x54>
  10a86a:    f005 f989     bl    10fb80 <__vPortEnterCritical_from_thumb>
  10a86e:    683b          ldr    r3, [r7, #0]
  10a870:    2b00          cmp    r3, #0
  10a872:    d101          bne.n    10a878 <prvIdleTask+0x28>
  10a874:    2400          movs    r4, #0
  10a876:    e003          b.n    10a880 <prvIdleTask+0x30>
  10a878:    4b0f          ldr    r3, [pc, #60]    (10a8b8 <.text+0x28b8>)
  10a87a:    3308          adds    r3, #8
  10a87c:    685b          ldr    r3, [r3, #4]
  10a87e:    68dc          ldr    r4, [r3, #12]
  10a880:    1d20          adds    r0, r4, #4
  10a882:    f7ff f921     bl    109ac8 <vListRemove>
  10a886:    4a0d          ldr    r2, [pc, #52]    (10a8bc <.text+0x28bc>)
  10a888:    6813          ldr    r3, [r2, #0]
  10a88a:    3b01          subs    r3, #1
  10a88c:    6013          str    r3, [r2, #0]
  10a88e:    6833          ldr    r3, [r6, #0]
  10a890:    3b01          subs    r3, #1
  10a892:    6033          str    r3, [r6, #0]
  10a894:    f005 f978     bl    10fb88 <__vPortExitCritical_from_thumb>
  10a898:    6b20          ldr    r0, [r4, #48]
  10a89a:    f7fe fe15     bl    1094c8 <vPortFree>
  10a89e:    1c20          adds    r0, r4, #0
  10a8a0:    f7fe fe12     bl    1094c8 <vPortFree>
  10a8a4:    4b06          ldr    r3, [pc, #24]    (10a8c0 <.text+0x28c0>)
  10a8a6:    681b          ldr    r3, [r3, #0]
  10a8a8:    2b01          cmp    r3, #1
  10a8aa:    d900          bls.n    10a8ae <prvIdleTask+0x5e>
  10a8ac:    df00          svc    0
  10a8ae:    f7fe fbb9     bl    109024 <vApplicationIdleHook>
  10a8b2:    e7d0          b.n    10a856 <prvIdleTask+0x6>

code with -O0:

0010954c <vApplicationIdleHook>:
  10954c:    b580          push    {r7, lr}
  10954e:    af02          add    r7, sp, #8
  109550:    4a03          ldr    r2, [pc, #12]    (109560 <.text+0x1560>)
  109552:    2301          movs    r3, #1
  109554:    6313          str    r3, [r2, #48]
  109556:    46bd          mov    sp, r7
  109558:    b082          sub    sp, #8
  10955a:    bc80          pop    {r7}
  10955c:    bc01          pop    {r0}
  10955e:    4700          bx    r0

0010c2a4 <prvIdleTask>:

/*
* -----------------------------------------------------------
* The Idle task.
* ----------------------------------------------------------
*
* The portTASK_FUNCTION() macro is used to allow port/compiler specific
* language extensions.  The equivalent prototype for this function is:
*
* void prvIdleTask( void *pvParameters );
*
*/
static portTASK_FUNCTION( prvIdleTask, pvParameters )
{
  10c2a4:    b580          push    {r7, lr}
  10c2a6:    b081          sub    sp, #4
  10c2a8:    af00          add    r7, sp, #0
  10c2aa:    1c3b          adds    r3, r7, #0
  10c2ac:    6018          str    r0, [r3, #0]
    /* Stop warnings. */
    ( void ) pvParameters;

    for( ;; )
    {
        /* See if any tasks have been deleted. */
        prvCheckTasksWaitingTermination();
  10c2ae:    f000 f8b7     bl    10c420 <prvCheckTasksWaitingTermination>

        #if ( configUSE_PREEMPTION == 0 )
        {
            /* If we are not using preemption we keep forcing a task switch to
            see if any other task has become available.  If we are using
            preemption we don’t need to do this as any task becoming available
            will automatically get the processor anyway. */
            taskYIELD();   
        }
        #endif

        #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
        {
            /* When using preemption tasks of equal priority will be
            timesliced.  If a task that is sharing the idle priority is ready
            to run then the idle task should yield before the end of the
            timeslice.
           
            A critical region is not required here as we are just reading from
            the list, and an occasional incorrect value will not matter.  If
            the ready list at the idle priority contains more than one task
            then a task other than the idle task is ready to execute. */
            if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 )
  10c2b2:    4b04          ldr    r3, [pc, #16]    (10c2c4 <.text+0x42c4>)
  10c2b4:    681b          ldr    r3, [r3, #0]
  10c2b6:    2b01          cmp    r3, #1
  10c2b8:    d900          bls.n    10c2bc <prvIdleTask+0x18>
            {
                taskYIELD();
  10c2ba:    df00          svc    0
            }
        }
        #endif

        #if ( configUSE_IDLE_HOOK == 1 )
        {
            extern void vApplicationIdleHook( void );

            /* Call the user defined function from within the idle task.  This
            allows the application designer to add background functionality
            without the overhead of a separate task.
            NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
            CALL A FUNCTION THAT MIGHT BLOCK. */
            vApplicationIdleHook();
  10c2bc:    f7fd f946     bl    10954c <vApplicationIdleHook>
        }
        #endif
    }
  10c2c0:    e7f5          b.n    10c2ae <prvIdleTask+0xa>

nobody wrote on Saturday, September 02, 2006:

for this code OS failed on:

Undef handler
OS tick count: 102
CurrentTCB: IDLE
parameters on TCB stack:
top of stack: 0x2014c4,
start of stack: 0x20106x
depth: 0x12c (x4)
critical nesting = 0
SPSR = 0x2000003f (main.c and tasks.c compiled in thumb mode)
R0 = 0x0010c2b3
R1 = 0x01010101
R2 = 0xfffff400
R3 = 0x00000001
R4 = 0x04040404
R5 = 0x05050505
R6 = 0x06060606
R7 = 0x0020150c
R8 = 0x08080808
R9 = 0x09090909
R10 = 0x10101010
R11 = 0x11111111
R12 = 0x12121212
R13 = 0x0020150c (SP)
R14 = 0x0010c2c1 (LR) <= it is wrong I think
R15 = 0x0010955c+instr (PC)

nobody wrote on Saturday, September 02, 2006:

my second task:
    xTaskCreate( vxTask, "vxTask", /*comSTACK_SIZE*/64+18+32, NULL, uxPriority + comRX_RELATIVE_PRIORITY, NULL );

static void vxTask( void *pvParameters )
{
    (void) pvParameters;

    while (1) {       
        AT91C_BASE_PIOA->PIO_CODR = LED4;
        vTaskDelay(( portTickType ) 500/*ms*/);
        AT91C_BASE_PIOA->PIO_SODR = LED4;
        vTaskDelay(( portTickType ) 500/*ms*/);
        //kprintf("abc\n");
    }
}

when I comment vTaskDelay system does not crash with -O0 and idle hook turned on!!!

what is going on???!!!!!!!