Replies: 3 comments 1 reply
-
Arduino UNO R3, with only 2 KB of SRAM, is not at all suitable for working with FreeRTOS, at most you can do a little demonstration by flashing an LED or something ... unfortunately, stack overflows are always lurking. Guglielmo |
Beta Was this translation helpful? Give feedback.
-
As noted the Uno is very limited in RAM. To get an idea of how limited it is start by deducting the Global Variables the Arduino IDE announces following compilation of your sketch from that 2kB total. Now deduct the Timer Task Stack of 92 Bytes and the Idle Task Stack of 192 Bytes (both you can configure). Out of the remaining Bytes you can allocate your Task Stacks. Noting that each Task requires at least 32 Stack Bytes to store the Task Control Block when it is swapped out, being mainly the MCU Resisters. And also at least 32 Bytes free to allow Timer Interrupts to trigger and their Registers to be saved during the interrupt. This is where the minimum Stack of 92 Bytes (32 + 32 + a bit more = see Whether a Timer Interrupt has fired is the background for why the Stack Highwater measure can seem variable. It can only detect the past marks of something being stored in those allocated Stack Bytes. But 2kB RAM is just enough to learn the FreeRTOS API and usage. Some time ago I also had issues with RAM and started working with ATmega2560 devices (Mega) as they can support 64kB with their external RAM capacity. But as their pin out is not the same as the Uno, many Shields don't work without modifications. Then later I found the ATmega1284p is the "Goldilocks" ATmega device with 16kB of RAM and designed and built first the Goldilocks, then the Goldilocks Analogue. I still use these systems today. |
Beta Was this translation helpful? Give feedback.
-
Oh ok! I get somehow confused because after build I get:
which suggested me that I still had plenty of room. But perhaps the RAM value does not include the heap memory that will be used in run-time, i.e. used by the tasks? |
Beta Was this translation helpful? Give feedback.
-
When my UNO gets stuck (usually due to the usage of
snprintf
or the serial port, typically) I took the habit of increasing the stack_size in thexCreateTask()
function. However, the way to set this parameter correctly does not seem trivial.For example, if I solve a problem by increasing it from
128
to256
, then I experienced that further increasing it e.g. to1024
, the board get stuck again.Also, I noticed that with exactly the same software,
uxTaskGetStackHighWaterMark()
gives different numbers depending on how much stack I have allocated for the given task. The problem is that those numbers are not what one could expect.I try to explain better with an example. Say that I have stack size equal to
256
for a task anduxTaskGetStackHighWaterMark() = 200
. Then, I expect that by setting the stack size to201
, then I should haveuxTaskGetStackHighWaterMark() = 1
, but instead I have a fairly random number that may be larger or smaller than200
.In-fact, I also happened to decrease the stack size and obtaining a higher value of
uxTaskGetStackHighWaterMark()
in front of a reduction of the stack_size (?!?).Why this behaviour? Is that due to some magic that happens during the dynamic memory allocation?
Shall I use
xCreateTaskStatic()
instead?In this way it is really difficult to find a correct way to set the stack size for the tasks because it does not seem true that the higher the better. This is a big issue as it rules out a general rule for fixing memory problems.
I am not sure if this strictly an Arduino_FreeRTOS_Library or a generic FreeRTOS library (in that case let me know so we close here and I ask the guys there).
Beta Was this translation helpful? Give feedback.
All reactions