FreeRTOS stuck at prvCheckTasksWaitingTermination

fedex03 wrote on Saturday, May 11, 2019:

I’m working with a Nucleo-STm32F767 and I had generated the code with CubeMX including FreeRTOS 9.

My code has 5 task and each task has a loop, where the task is suspended on each iteration.

  while( 1 )
  {   
        //Do something

        osDelay(TASK_MAIN_DELAY_MS);
  }

At this point my system works well.

Now I added a task that handle the communication with an SPI network controller. The network controller has it own middleware written in C.

Now every time I try to suspend a task (with osDelay) my code is stucked into prvCheckTasksWaitingTermination and my system is blocked forever.

static void prvCheckTasksWaitingTermination( void )
{

	/** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/

	#if ( INCLUDE_vTaskDelete == 1 )
	{
		BaseType_t xListIsEmpty;

		/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
		too often in the idle task. */
		while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
		{
			vTaskSuspendAll();
			{
				xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
			}
			( void ) xTaskResumeAll();

			if( xListIsEmpty == pdFALSE )
			{
				TCB_t *pxTCB;

				taskENTER_CRITICAL();
				{
					pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
					( void ) uxListRemove( &( pxTCB->xStateListItem ) );
					--uxCurrentNumberOfTasks;
					--uxDeletedTasksWaitingCleanUp;
				}
				taskEXIT_CRITICAL();

				prvDeleteTCB( pxTCB );
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
	}
	#endif /* INCLUDE_vTaskDelete */

In particular, the execution is stopped here: while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) becuase uxDeletedTasksWaitingCleanUp is equal to 0.

I don’t know how to resolve this issue :frowning:

Anybody can help me?

Thanks and best regards, Federico

richarddamon wrote on Sunday, May 12, 2019:

if uxDeletedTasksWaitingCleanUp is 0, the while loop should end immediately and the function return.

heinbali01 wrote on Sunday, May 12, 2019:

When you debug a FreeRTOS application that is mostly idle, and press “pause”, chances are big that your hit on a few lines of code in the idle handler, like the function prvCheckTasksWaitingTermination(). There is nothing wrong with that code.

Can I assume that osDelay() is actually a call to the FreeRTOS API vTaskDelay()?

You write that you’re using an SPI network controller, that is quite complex software. As it is a network controller, so are you also using a TCP/IP stack? Which one?

When a simple task like:

    while( 1 )
    {   
        osDelay(TASK_MAIN_DELAY_MS);
    }

doesn’t wake-up anymore, I would suspect some corruption, probably a stack that was too small, thus corrupting memory used by the kernel or other tasks.

fedex03 wrote on Sunday, May 12, 2019:

Hello Hein,

the osDelay is a CMSIS wrapper for the vTaskDelay.

osStatus osDelay (uint32_t millisec)
{
#if INCLUDE_vTaskDelay
  TickType_t ticks = millisec / portTICK_PERIOD_MS;
  
  vTaskDelay(ticks ? ticks : 1);          /* Minimum delay = 1 tick */
  
  return osOK;
#else
  (void) millisec;
  
  return osErrorResource;
#endif
}

The middleware that I’m using is cifX Toolk. A toolkit for a fieldbus network interface.

What I saw is the before I complete the initialization of this toolkit the vTaskDelay function works.
After a the execution of a function in the toolkit , the vTaskDelay stop to works.
This toolkit has a file where user should define sono wrapping function and in embedded system the function to be wrapped are:

/*****************************************************************************/
/*! Sleep for a specific time
*   \param ulSleepTimeMs  Time in ms to sleep for                            */
/*****************************************************************************/
void OS_Sleep(uint32_t ulSleepTimeMs)
{
  uint32_t startTime   = 0;

  if( ulSleepTimeMs != 0 )
  {
    startTime = OS_DelayCnt;
    do
    {
    }
    while ((OS_DelayCnt - startTime) < ulSleepTimeMs);
  }
}

Here in this function, initially I used my osDely function, but I was thinking that the unresumed task problem is due to this function, so I changed it with the above implementation (it is not elegant).
To compute the delay in this function I use a software time that increments the OS_DelayCnt every millisecond. This software timer (no RTOS timer, I implemented it) use the interrupt of an HW timer.

And the other function that I wrapped is:

/*****************************************************************************/
/*! Retrieve a counter based on millisecond used for timeout monitoring
*   \return Current counter value (resolution of this value will influence
*           timeout monitoring in driver/toolkit functions(                  */
/*****************************************************************************/
uint32_t OS_GetMilliSecCounter(void)
{
  return OS_DelayCnt;
}

I increas the heap, because this toolkit uses malloc function.

Really, I don’t understand why my task is not resumed.
In this project is an evolution of a previous project that worked very well with FreeRTOS but now I run out of idead!

Thanks a lot for the help!

Best regards,
Federico

rtel wrote on Sunday, May 12, 2019:

First, but unrleated, the implementation of osDelay() is wrong as 0 is a perfectly valid input and should be equivalent to calling taskYIELD().

In this case I’m going to guess your third party driver is doing somethign that stops or masks the tick interrupt. If the tick is not working time will effectively be stopped and delays won’t end.

View the xTickCount variable in the debugger when you are stuck in the idle task (which, as Hein pointed out, is where that function is). Does it change? It should be incrementing.

I encountered the same problem as you. How did you finally solve it?
thx.