Stack on static

enrico_adelco wrote on Friday, November 07, 2008:

Hi all,
I’m using FreeRTOS on a board with external SDRAM and LPC2478. As I have some collision on external bus (as I located HEAP on external RAM), I would like to know if is possible to set STACK of each task on static (and for me) internal RAM
If yes, I’m able to avoid access to external RAM on each PUSH/POP improving performance

Note that I placed HEAP on external ram as I need a lot of it, I’m using FLTK for GUI.
Thank you
Enrico Dalla Mariga

rtel wrote on Friday, November 07, 2008:

The stacks are allocated from the FreeRTOS.org heap - normally from heap_1.c or heap_2.c.  This is separate from the heap your linker script will probably setup, so if you main heap is in external RAM you should be able to setup the FreeRTOS.org heap to use internal RAM.  How this is done will depend on the compiler and linker as each uses its own syntax for placement.

Regards.

enrico_adelco wrote on Tuesday, November 11, 2008:

But I used heap model heap_3.c, to be able to allocate dynamic object in secure section (with vTaskSuspendAll and xTaskResumeAll)
I created 2 macros, “MALLOC” and “FREE” so that every allocation/free in any sources uses FreeRTOS function avoiding any conflict due to overlapped allocation. In other words, if I use malloc in 2 different task, I have to be sure to make it in critical region as if I will be interrupted during malloc by another task that want to make another malloc, I think (never tried) that it will soon crash!!!
It would be useful to allow xTaskCreate to get pointer to static STACK, which can be in HEAP or not
What do you think?
I need these improvements as I’m working in critical condition (ARM7 LPC2478 with external RAM, LCD 800x480 and FLTK+nanoX+microwindows over FreeRTOS)
Thanks in advance

enrico_adelco wrote on Tuesday, November 11, 2008:

Here follow a patch to apply FreeRTOS 5.1.0 to have STACK and TCB as static and not dynamic memory. It needs following macros:

#define configUSE_STATIC_STACK   1
#define configUSE_STATIC_TCB     1
#if (configUSE_STATIC_TCB == 1)
#define configMAX_TASK_NUMBER  4
#endif

Patch is:
— D:/FreeRTOS_5.1.0/Source/tasks.c    Fri Oct 24 18:57:34 2008
+++ D:/FreeRTOS/Source/tasks.c    Tue Nov 11 14:43:36 2008
@@ -146 +146,3 @@
-
+#if (configUSE_STATIC_TCB == 1)
+static tskTCB tasks[configMAX_TASK_NUMBER];
+#endif
@@ -364,0 +367,3 @@
+#if (configUSE_STATIC_STACK == 1)
+  pxNewTCB->pxStack = (portSTACK_TYPE *)pvParameters;
+#endif 
@@ -396 +401,7 @@
-        pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pvTaskCode, pvParameters );
+    pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pvTaskCode,
+#if (configUSE_STATIC_STACK == 1)                                                   
+                                                    0
+#else                                                   
+                                                    pvParameters
+#endif                                                   
+                                                     );
@@ -963 +974,3 @@
-
+#if (configUSE_STATIC_STACK == 1)
+static portSTACK_TYPE idleStack[tskIDLE_STACK_SIZE];
+#endif
@@ -969 +982,7 @@
-    xReturn = xTaskCreate( prvIdleTask, ( signed portCHAR * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
+  xReturn = xTaskCreate( prvIdleTask, ( signed portCHAR * ) "IDLE", tskIDLE_STACK_SIZE, ( void * )
+#if (configUSE_STATIC_STACK == 1)   
+                         idleStack
+#else 
+                         NULL
+#endif
+                         , tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
@@ -1784,0 +1804,3 @@
+#if (configUSE_STATIC_TCB == 1)
+  pxNewTCB = &tasks[uxCurrentNumberOfTasks];
+#else 
@@ -1787,0 +1810 @@
+#endif 
@@ -1788,0 +1812 @@
+#if (configUSE_STATIC_STACK == 0)
@@ -1807,0 +1832 @@
+#endif

When you create a new task, you have to pass, on pvParameters, pointer to portSTACK_TYPE array of number of elements equal to usStackDepth. For example:

#define MY_STACK_SIZE 100
static portSTACK_TYPE myStack[MY_STACK_SIZE];

xTaskCreate(task1, "Task1", MY_STACK_SIZE, myStack, TASK_PRIORITY, NULL);

Make sure that configMAX_TASK_NUMBER is more or equal than xTaskCreate calls.

NOTES:
- Tested on ARM7 LPC2000 porting (LPC2478 w/external memory and LCD)
- No support for vTaskDelete!!! TCB location are not free’d
- No check for array of TCB insufficient

These changes are very useful if you use dynamic allocation (malloc/free) in HEAP located on external memory. After these changes, my application duplicated speed on widgets drawing