Minimum bound for stack sizes

Greetings. I’ve been working with FreeRTOS on the SAM7S32. I ended up chasing down a nasty funny, in that, I had an application which was calling vTaskDelay(10); but was never being re-scheduled. I ended up instruction stepping xTaskDelay(); To cut a long story short – FreeRTOS’ practice of saving context on the user’s stack in portSAVE_CONTEXT(); – rather than on the ISR’s stack – I believe – with respect – is a bit backwards. Reason being the following – the pvOwner – which is a pointer to the TCB of the task that did the xTaskDelay(); is at 0x2006c0. At this point in time the task calling xTaskDelay(); has been configured with a stack of 0x18 * 4 words – or 96 bytes, which I was thinking was generous on 8k of SRAM. However at vPortYieldProcessor+44 – you’ll see that the ARM assembler is subtracting 60 bytes from the link register. The link registers is in fact the stack pointer – plus or minus a few words of the CALLING task – not the ISR context we are in a this point. Hence : if the stack size of the calling task is below a certain size ~ 1xx bytes the context switching code of the ISR will overflow the tasks stack. I was loathe to go changing the context switching code – without a full understanding of all aspects of it – however – I think it would be a good idea to have at the very least an #if configMINIMAL_STACK_SIZE < SOME_MINIMUM_SIZE_FOR_CONTEXT_SWITCHING     #error "Your stack will overflow me auld flower" #endif just to ATTEMPT to idot proof – even against sufficiently talented idots such as myself ! Cheers, Bryan [code] $7 = (volatile struct xLIST_ITEM *) 0x2006c0 (gdb) print &pxDelayedTaskList->xListEnd->pxNext->pvOwner $8 = (void **) 0x2006cc (gdb) disass Dump of assembler code for function vPortYieldProcessor: 0x0010432c <vPortYieldProcessor+0>:     add     lr, lr, #4      ; 0x4 0x00104330 <vPortYieldProcessor+4>:     push    {r0} 0x00104334 <vPortYieldProcessor+8>:     stmdb   sp, {sp}^ 0x00104338 <vPortYieldProcessor+12>:    nop                     (mov r0,r0) 0x0010433c <vPortYieldProcessor+16>:    sub     sp, sp, #4      ; 0x4 0x00104340 <vPortYieldProcessor+20>:    pop     {r0} 0x00104344 <vPortYieldProcessor+24>:    stmdb   r0!, {lr} 0x00104348 <vPortYieldProcessor+28>:    mov     lr, r0 0x0010434c <vPortYieldProcessor+32>:    pop     {r0} 0x00104350 <vPortYieldProcessor+36>:    stmdb   lr, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r1 1, r12, sp, lr}^ 0x00104354 <vPortYieldProcessor+40>:    nop                     (mov r0,r0) 0x00104358 <vPortYieldProcessor+44>:    sub     lr, lr, #60     ; 0x3c 0x0010435c <vPortYieldProcessor+48>:    mrs     r0, SPSR 0x00104360 <vPortYieldProcessor+52>:    stmdb   lr!, {r0} 0x00104364 <vPortYieldProcessor+56>:    ldr     r0, [pc, #404]  ; 0x104500 0x00104368 <vPortYieldProcessor+60>:    ldr     r0, [r0] 0x0010436c <vPortYieldProcessor+64>:    stmdb   lr!, {r0} 0x00104370 <vPortYieldProcessor+68>:    ldr     r0, [pc, #388]  ; 0x1044fc 0x00104374 <vPortYieldProcessor+72>:    ldr     r0, [r0] 0x00104378 <vPortYieldProcessor+76>:    str     lr, [r0] 0x0010437c <vPortYieldProcessor+80>:    ldr     r3, [pc, #76]   ; 0x1043d0 <vPortYieldProcessor+164> 0x00104380 <vPortYieldProcessor+84>:    ldr     r3, [r3] 0x00104384 <vPortYieldProcessor+88>:    ldr     r3, [pc, #72]   ; 0x1043d4 <vPortYieldProcessor+168> 0x00104388 <vPortYieldProcessor+92>:    ldr     r3, [r3] 0x0010438c <vPortYieldProcessor+96>:    bl      0x102d9c <vTaskSwitchContext> 0x00104390 <vPortYieldProcessor+100>:   ldr     r0, [pc, #356]  ; 0x1044fc 0x00104394 <vPortYieldProcessor+104>:   ldr     r0, [r0] 0x00104398 <vPortYieldProcessor+108>:   ldr     lr, [r0] 0x0010439c <vPortYieldProcessor+112>:   ldr     r0, [pc, #348]  ; 0x104500 0x001043a0 <vPortYieldProcessor+116>:   ldm     lr!, {r1} 0x001043a4 <vPortYieldProcessor+120>:   str     r1, [r0] 0x001043a8 <vPortYieldProcessor+124>:   ldm     lr!, {r0} 0x001043ac <vPortYieldProcessor+128>:   msr     SPSR_fc, r0 0x001043b0 <vPortYieldProcessor+132>:   ldm     lr, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r1 1, r12, sp, lr}^ 0x001043b4 <vPortYieldProcessor+136>:   nop                     (mov r0,r0) 0x001043b8 <vPortYieldProcessor+140>:   ldr     lr, [lr, #60] 0x001043bc <vPortYieldProcessor+144>:   subs    pc, lr, #4      ; 0x4 0x001043c0 <vPortYieldProcessor+148>:   ldr     r3, [pc, #8]    ; 0x1043d0 <vPortYieldProcessor+164> 0x001043c4 <vPortYieldProcessor+152>:   ldr     r3, [r3] 0x001043c8 <vPortYieldProcessor+156>:   ldr     r3, [pc, #4]    ; 0x1043d4 <vPortYieldProcessor+168> 0x001043cc <vPortYieldProcessor+160>:   ldr     r3, [r3] 0x001043d0 <vPortYieldProcessor+164>:   eoreq   r0, r0, r4 0x001043d4 <vPortYieldProcessor+168>:   eoreq   r0, r0, r0, asr r4 End of assembler dump. (gdb) info registers r0             0x0      0 r1             0x0      0 r2             0x0      0 r3             0x0      0 r4             0x4040404        67372036 r5             0x5050505        84215045 r6             0x6060606        101058054 r7             0x7070707        117901063 r8             0x8080808        134744072 r9             0x9090909        151587081 r10            0x10101010       269488144 r11            0x11111111       286331153 r12            0x12121212       303174162 sp             0x200ed8 0x200ed8 lr             0x2006d0 2098896 pc             0x10436c 0x10436c <vPortYieldProcessor+64> fps            0x0      0 cpsr           0x60000093       1610612883 (gdb) print &pxDelayedTaskList->xListEnd->pxNext->pvOwner $9 = (void **) 0x2006cc (gdb) print pxDelayedTaskList->xListEnd->pxNext->pvOwner $10 = (void *) 0x2006bc (gdb) stepi 0x00104370      186        portSAVE_CONTEXT(); (gdb) print pxDelayedTaskList->xListEnd->pxNext->pvOwner $11 = (void *) 0x0 (gdb) print &pxDelayedTaskList->xListEnd->pxNext->pvOwner $12 = (void **) 0x2006cc (gdb) q The program is running.  Exit anyway? (y or n) y [/code]

Minimum bound for stack sizes

The context cannot be saved on the IRQ stack because the stack frame has to exist until the task next runs, the IRQ stack frame will be clobbered the next time a task runs. Take a look at number 1 on this page, including the links. These should help. http://www.freertos.org/FAQHelp.html