Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


Minimum bound for stack sizes

Posted by Bryan O'Donoghue on November 23, 2008

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

#error "Your stack will overflow me auld flower"

just to ATTEMPT to idot proof - even against sufficiently talented idots such as myself !


$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

RE: Minimum bound for stack sizes

Posted by Dave on November 23, 2008
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.

[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists