Skip to content
\n

I think it's strange to see that stack overflow occurs after the task has looped some times. The memory requirement for each loop is stable, no malloc, no recursion. And more strangely, when configCHECK_FOR_STACK_OVERFLOW == 1, the task is happy with 300 stack size. However, when configCHECK_FOR_STACK_OVERFLOW == 2, 500 bytes of stack space is still insufficient.

\n

I used uxTaskGetStackHighWaterMark() in the deepest stage of the function call. The result shows the task has more than half the total size of stack space remaining available, and suddenly crashes. Considering the algorithm taken by FreeRTOS core when configCHECK_FOR_STACK_OVERFLOW == 2, there must be something modified the data in stack. I think it is the ISR. When configCHECK_FOR_STACK_OVERFLOW == 1, the risk can't be detected.

\n

\"图片\"

\n

My project is build under PlatformIO. If you want more detail, below is all the files. Note that, most comments are written in chinese, and most code is c++, template magic warning.

\n

project.zip

","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"
\n

As for AVR devices, I suspect ISR just use the stack of the task interrupted by the ISR, and randomly cause stack overflow.

\n
\n

Yes. The stack used during a context switch is the active Task stack. This is why every Task stack must be large enough to support all of the stack used by the Task itself, plus enough free space to enable a context switch to be stored.

\n

This means that if your Task doesn't reuse dynamic storage properly then sooner or later there will be a crash due to stack overflow. If there is a stack overflow happening, that points to something arising in the Task code itself.

\n

Usually a Task will be allocated memory by a static allocation solution such as heap_1.c or heap_2.c. But in the case of Arduino_FreeRTOS we've used the standard malloc() code wrapped by heap_3.c as it allows support of various different devices with different memory capacities.

\n

For professional work I'd suggest not to use heap_3.c as your memory manager. And consider using the static versions of the FreeRTOS API.

\n

It also means that you have to assume that a context switch will occur at the most inconvenient time. This is 100% guarenteed to happen over the long run (only several seconds in FreeRTOS world). As an example where this affected me, in the 8-bit Z80 world the RomWBW system uses bank switching to access system utilities and interrupt code stored in a separate code page. If (When) a FreeRTOS context switch happens during the process of doing the bank switch, then stack space needs to be available for it to complete. For clarity, this is not before the bank switch running in user memory, or after while running in system memory, but during the actual bank switch even though this is a very short piece of code.

\n

Hope that helps.

","upvoteCount":1,"url":"https://github.com/feilipu/Arduino_FreeRTOS_Library/discussions/144#discussioncomment-12519025"}}}
Discussion options

You must be logged in to vote

As for AVR devices, I suspect ISR just use the stack of the task interrupted by the ISR, and randomly cause stack overflow.

Yes. The stack used during a context switch is the active Task stack. This is why every Task stack must be large enough to support all of the stack used by the Task itself, plus enough free space to enable a context switch to be stored.

This means that if your Task doesn't reuse dynamic storage properly then sooner or later there will be a crash due to stack overflow. If there is a stack overflow happening, that points to something arising in the Task code itself.

Usually a Task will be allocated memory by a static allocation solution such as heap_1.c or heap_2.c. …

Replies: 1 comment

Comment options

You must be logged in to vote
0 replies
Answer selected by marshfolx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants