Using FreeRTOS makes very little difference to the stack size - the
stack size depends on how the compiler uses it (which will be different
at different optimisation levels), the function call nesting depth, and
the variables your code places on the stack - just like in any C
program. The difference when using FreeRTOS (or any preemptive RTOS) is
that you have more than one stack - one per task - so you can try to
minimise the number of tasks you create.
Some C libraries are real stack hogs too, so choose an optmized library
implementation.
You can view stack sizes using several functions, including https://www.freertos.org/uxTaskGetStackHighWaterMark.html - that enables
you to tune the size as you can see if the current size is too large or
too small. Likewise you can tune the heap size using
xPortGetMinimumEverFreeHeapSize().
Okey, so by using the uxuxHighWaterMark method i can fine tune the amount of stacksize needed for each task?
If i then understand you correctly, rtos will do the memory handling for me? So i dont need any realloc(); or malloc(); from freertos lib?
As you say, you can use uxHighWaterMark to check stack usage and adjust your stack size based on it (be sure to leave a bit of slack). FreeRTOS will aquire the needed memory to create that stack for you (unless you use the âStaticâ task creation routine, where you provide the needed array, assume to be allocated as static memory)
If your tasks need any dynamic memory, they will need to call the allocation functions themselves. This is just like for any normal program, the only difference is that with multiple tasks, you have multiple task stacks, so you have to allocate the desired amount to each of them.
When im trying to use the uxHighwatermark function i get an error from visual studio:
Compiling .pioenvs\megaatmega2560\src\main.cpp.o
src\main.cpp:16:63: error: ambiguating new declaration of âUBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t)â
UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t Startpump);
^
In file included from lib\FreeRTOS\src/FreeRTOSVariant.h:56:0,
from lib\FreeRTOS\src/Arduino_FreeRTOS.h:1270,
from src\main.cpp:2:
lib\FreeRTOS\src/task.h:1440:24: note: old declaration âuint16_t uxTaskGetStackHighWaterMark(TaskHandle_t)â
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
^
*** [.pioenvs\megaatmega2560\src\main.cpp.o] Error 1
I am currently using 10.2.0v of freertos, i have also read more about usage of uxTaskGetStackHighWatermark, and now it prints, but all i get is a questionmark symbol for each time the task is used.
A snip of my code:
void Startpump(void *pvParameters);
xTaskCreate(
Startpump, // Function name
âTurn on pumpâ, // What it does
128, // Stack size in words
NULL, // Parameter for task, usually NULL
1, // Priority of the task
NULL // Task handle, usually NULL
);
vTaskStartScheduler();
The funtion itself:
void Startpump(void *pvParameters)
{
// Initialize on and off button
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(motorPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
// Task commands for delay og minnehÄndtering(sjekke verdier hver task spytter ut)
// Delay mellom task
const TickType_t xDelay = 100 / portTICK_PERIOD_MS;
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
for (;;)
{
// Leser status pÄ knappene
buttonStatus1 = digitalRead(buttonPin1);
buttonStatus2 = digitalRead(buttonPin2);
if (buttonStatus1 == HIGH && buttonStatus2 == LOW) // PĂ„ knappen trykket
{
digitalWrite(motorPin, HIGH);
digitalWrite(greenLedPin, HIGH);
digitalWrite(redLedPin, LOW);
LEDstatus = 1;
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
Serial.println(uxTaskGetStackHighWaterMark(NULL));
vTaskDelay(xDelay);
}
else if(buttonStatus1 == LOW && buttonStatus2 == HIGH) // Av knappen er trykket
{
digitalWrite(motorPin, LOW);
digitalWrite(greenLedPin, LOW);
digitalWrite(redLedPin, HIGH);
LEDstatus = 0;
Serial.print(F("Watermark stack er: "));
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
Serial.println(uxTaskGetStackHighWaterMark(NULL));
vTaskDelay(xDelay);
}
}
Which bit is not working? Just the printing? If so, canât help you
there as the print function you are using is not something we wrote -
but to check the uxTaskGetStackHighWaterMark() function you can simple
place a break point in the code to see its return value.