FreeRTOS, idle hook and gcc
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
FreeRTOS, idle hook and gcc
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>
FreeRTOS, idle hook and gcc
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)
FreeRTOS, idle hook and gcc
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("abcn");
}
}
when I comment vTaskDelay system does not crash with -O0 and idle hook turned on!!!
what is going on???!!!!!!!