-
I wonder where is the stack used by ISR. Cortex-M devices have two SP registers so that ISR and tasks use seperate stack spaces. But AVR devices don't seem to have this capability. As for AVR devices, I suspect ISR just use the stack of the task interrupted by the ISR, and randomly cause stack overflow. I made a fork of this project to support ATmega128, and changed a little code to use TIM2 as tick source. I found that, when I define configCHECK_FOR_STACK_OVERFLOW == 2, the stack overflow alert is triggered more often. The structure of my code is like below: void main_task() {
// SETUP
Wire.begin();
init_pin();
init_oled();
put_something_on_oled();
// LOOP
int counter = 0;
while(true) {
put_num_to_oled(counter);
// crash near here
++counter;
xTaskDelay(500ms);
}
} 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. I used 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. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
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 For professional work I'd suggest not to use 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. Hope that helps. |
Beta Was this translation helpful? Give feedback.
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
orheap_2.c
. …