Task Silently Failing to Schedule After Increasing Its Stack Size

erscott wrote on Thursday, November 07, 2019:

Hello! I am working with a TI MSP430FR2476 with FreeRTOS v10.2.1, using CCS as the IDE.

I recently encountered an issue while working on an application with 3 tasks, all created from another “initialization” task. One of my tasks (the last one to be created) was overflowing its stack, so I tried increasing the task’s stack size. I found that, after increasing it’s stack past a certain size, the task would never get run. My breakpoints within this task never get hit. There was no failed malloc or stack overflow error, and all of the other tasks are running as normal. I even used uxTaskGetSystemState to check the states of all of the tasks throughout execution of my application, and this failing task was always marked as ready, but it was never getting run. I’ve attached my FreeRTOSConfig.h.

Below is a list of all of the things I’ve tried as I was debugging this, and their resulting effects:

  • Increasing the heap size for C/C++ dynamic memory allocation in CCS - no change
  • Increasing the FreeRTOS heap size - no change
  • Increasing the stack size for the failing task past the amount of available memory - stack overflow error as expected
  • Increasing the priority of the failing task - no change
  • Checking for failed malloc and stack overflow - doesn’t occur
  • Creating the tasks in a different order - this generally causes some tasks to schedule and other to not run
  • Replacing the failing task with a task that just does nothing - no change
  • Creating a task after the failing task - new task does run, failing task still doesn’t

I ended up finding a band-aid solution, where if I create a task that does nothing right before creating the failing task, and give it the same stack size as the failing task, the failing task will run and the task that does nothing will not.

Is there anything that I might be missing here that could be causing this strange behavior? Maybe some sort of resource constraint parameter that I’m missing?

Thanks!

heinbali01 wrote on Thursday, November 07, 2019:

One of my tasks (the last one to be created) was overflowing its stack

You say that it doesn’t help to increase its stack-size, and also the increasing it too much, will prevent it from running. That sounds like a more generic memory corruption.
Are you sure that the memory corruption is caused by a stack overflow?

Does the code declare large objects in the stack space?

Replacing the failing task with a task that just does nothing - no change

It is important that the empty task calls at least vTaskDelay() to let lower-priority tasks run.

Are you aware of these task priorities, and the necessity to yield?

About your FreeRTOSConfig.h : are you really using the FreeRTOS timers (configUSE_TIMERS)? If no, it is cheaper to set that macro to 0.

It is difficult to say more without seeing your code.

erscott wrote on Thursday, November 07, 2019:

Thanks for replying.

Are you sure that the memory corruption is caused by a stack overflow?

Yes, I know that the task was having a stack overflow before I started increasing the stack size - the stack overflow hook was being called with the task’s name when the task started running. So I tried increasing the stack size, and it doesn’t get run, and then I increase it too much and I get a failed malloc. The code does not create any really large objects within the stack space of a task, the largest would be some long doubles .

Are you aware of these task priorities, and the necessity to yield?

Yes, I am aware of priority mechanics. The task that does nothing has the same priority as the other tasks, so it will not monopolize CPU time. The other tasks are still running, so there’s no issue with one task taking up all CPU time. I did try increasing the priority of the failing task to be greater than the other tasks, but it still doesn’t get run.

About your FreeRTOSConfig.h : are you really using the FreeRTOS timers (configUSE_TIMERS)? If no, it is cheaper to set that macro to 0.

I am not using FreeRTOS timers, so I could remove that.