Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
194 views
in Technique[技术] by (71.8m points)

FreeRTOS - The reason for the stack increase?

I have created several tasks, the body of which is the same function. Inside the function, there is a delay that is the same for every task. So, when this delay is large enough, the stack of each task is filled with 6 words less than when the delay is less. As far as I understand, the stack of tasks increases when there is a situation with several tasks with the status Ready.

1.In this situation, some additional 6-word context is written to the task stack?

2.In my example, it turns out 6 words (24 bytes), can this value change somehow?

3.What else can affect the increase in the stack, such as jumping into an interrupt handler?

int main(void){
  xTaskCreate(Task_PrintCountString, "Task_1", mySTACK_SIZE, &param1, 1, NUUL);
  xTaskCreate(Task_PrintCountString, "Task_2", mySTACK_SIZE, &param2, 1, NUUL);
  xTaskCreate(Task_PrintCountString, "Task_3", mySTACK_SIZE, &param3, 1, NUUL);
  vTaskStartScheduler();
}
#define myDELAY     100
void Task_PrintCountString(void *pParams){
  uint16_t c=0; 
  for(;;){
    if(xSemaphoreTake(WriteCountMutex, portMAX_DELAY) == pdTRUE){
        PrintCountString(*(uint8_t *)pParams, c++);
        xSemaphoreGive(WriteCountMutex);
    }       
  vTaskDelay(myDELAY/portTICK_PERIOD_MS);//When myDELAY=1, the task stack is 6 words more than when myDELAY= 100!       
  } 
}

enter image description here

Address 0x20000158 is the top of the stack for one of the tasks. Similarly, others!

The only function PrintCountString always the same depth. But at the same time, the stack can grow to its maximum knowledge in several stages, going through dozens of iterations of the task cycle! It turns out that not only the context is saved to the stack, but something else?

P.S. I use ARM CM0 port and heap_1.

I made an observation: In the PrintCountString function there was a block for waiting for the SPI flag - while(). I replaced the DMA transfer method and removed the while() loop. The stack of both tasks began to fill up immediately to the maximum value, regardless of delays.

question from:https://stackoverflow.com/questions/65859359/freertos-the-reason-for-the-stack-increase

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In general the stack memory is used by the microcontroller itself. There are several instructions which writes/reads some data to/from the stack.

  • The PUSH instruction copies the content of one register to the stack and modifies the stack pointer register
  • The POP instruction reads a word from the stack into a register and modifies the stack pointer register

Both instructions are managed by the compiler. If a functions is executed the compiler creates some PUSH instructions to "free" some registers to work with. At the end of the function the original register state will be restored using the POP instructions to guarantee the upcoming control flow.

  • and each branch instruction stores several register values to the stack

The amount of used stack memory depends on the call hierarchy.

According to your example, if the SemaphoreTake function is called and finds a released semaphore the call hierarchy is different from a situation where the semaphore is blocked. This creates a different stack usage.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...