Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Determining optimal stack usage.

Posted by znatok on December 8, 2014

HI, I have a project with 10 to 20 tasks running depending on configuration and active connections (TCP server, ...). I want to optimize stack usage by every single task and for that I'm about to use uxTaskGetStackHighWaterMark() http://www.freertos.org/uxTaskGetStackHighWaterMark.html

But I'd like to check stack usage of all tasks and not only some specific. So I need a functionality to walk over all tasks. Unfortunately I do not see a way to do it without turning on costly configUSETRACEFACILITY . From the other hand scheduler must have a list or lists of ALL tasks somewhere and this should not be related to TRACEFACILITY. My question is if I can get access to task handlers list(s) without TRACEFACILITY ?


Determining optimal stack usage.

Posted by davedoors on December 8, 2014

The Eclipse, IAR, and various other, IDE plugins will show you the RAM usage. Otherwise temporarily hack the code to loose the configUSETRACEFACILITY guards then use uxTaskGetSystemState().


Determining optimal stack usage.

Posted by znatok on December 8, 2014

I do not use IDE. I need to get stack real time usage information. Still is where a way to get access to the task handlers list in some way?

On Mon, Dec 8, 2014 at 7:49 PM, Dave davedoors@users.sf.net wrote:

The Eclipse, IAR, and various other, IDE plugins will show you the RAM usage. Otherwise temporarily hack the code to loose the

configUSETRACEFACILITY guards then use uxTaskGetSystemState().

Determining optimal stack usage.

Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/

To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/


Determining optimal stack usage.

Posted by markwrichardson on December 9, 2014

I did the following . . .

The current running job info is application specific, but you should get the idea

~~~~~~ //====================================================================== // // notes for below //====================================================================== /* -- TaskStatust type TaskHandlet xHandle - The handle of the task const signed char * pcTaskName - A pointer to the task's name unsigned BaseTypet xTaskNumber - A number unique to the task eTaskState eCurrentState - Task state unsigned BaseTypet uxCurrentPriority - task Priority unsigned BaseType_t uxBasePriority - Normal Priority unsigned long ulRunTimeCounter - Total Run time unsigned short usStackHighWaterMark - smallest stack remaining so far

eTaskState
'G'	eRunning = 0,	 A task is querying the state of itself, so must be running. 
'R'	eReady,			 The task being queried is in a read or pending ready list. 
'B'	eBlocked,		 The task being queried is in the Blocked state.
'S'	eSuspended,		 The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. 
'D'	eDeleted		 The task being queried has been deleted, but its TCB has not yet been freed. 

*/

// put here instead of altering the distro void * xTimerGetTimerDaemonTaskHandle( void );

//{ "TASKLIST", "Show all tasks and stats", 0,0, "", { 0 }, 0, 'N', ' ', 's', '=', &cmdTASKLIST }, //====================================================================== // // report task statistics to the console //====================================================================== int cmdTASKLIST( CMDARG *args ) { TaskStatust TaskInfo[1 + TCBASICTASKS + TCMAXJOBTASKS + 1]; unsigned portCHAR TaskCnt; unsigned portLONG TotalRunTime; unsigned portCHAR TaskIdx; portCHAR st; sizet FreeHeap; TASKCTLITEM *pTCI; char CmdString[41]; char Jobstate; CMDJOBNO JobNumber; uint16_t StackSize; char LockListBuffer[100];

vTaskSuspendAll();

TaskCnt = uxTaskGetSystemState( TaskInfo, (1 + TC_BASICTASKS + TC_MAXJOBTASKS + 1), &TotalRunTime);

CIOCommandOutLine("Name           Tn S  P  p RunTime StkRmn/StkSiz St JobNum CmdString");


for(TaskIdx = 0; TaskIdx < TaskCnt; TaskIdx ++)
{
	switch (TaskInfo[TaskIdx].eCurrentState)
	{
		case eRunning:
			st = 'G';
			break;
		case eReady:
			st = 'r';
			break;
		case eBlocked:
			st = 'b';
			break;
		case eSuspended:
			st = 's';
			break;
		case eDeleted:
			st = 'd';
			break;
		default:
			st = '?';
			break;
	};

	pTCI = (TASKCTLITEM *) xTaskGetApplicationTaskTag( TaskInfo[TaskIdx].xHandle );

	if (pTCI)
	{
		if (pTCI->Job )				// JobInfo gets set to zero after Jobstate;
		{
			strncpy(CmdString, pTCI->Job->Args.cmdinput, 40);
		}

		JobNumber = pTCI->Job->JobNo;
		Jobstate = pTCI->JobState;		// get Jobstate after and test in case job ends
		StackSize = pTCI->StackSize;

		if (Jobstate != TC_NOJOB)
		{
			CmdString[40] = 0;
			LockListBuffer[0] = 0;
			RSLMakeListAllDomainLocksForTaskId( pTCI, LockListBuffer );
		}
		else
		{
			// if no job, don't trust job info
			CmdString[0] = 0;		
			JobNumber = 0;
			Jobstate = ' ';
			LockListBuffer[0] = 0;
		}
	}
	else
	{
		if (TaskInfo[TaskIdx].xHandle == xTaskGetIdleTaskHandle())
		{
			Jobstate = ' ';
			CmdString[0] = 0;
			JobNumber = 0;
			StackSize = configMINIMAL_STACK_SIZE;
		}
		else if (TaskInfo[TaskIdx].xHandle == xTimerGetTimerDaemonTaskHandle())
		{
			Jobstate = ' ';
			CmdString[0] = 0;
			JobNumber = 0;
			StackSize = configTIMER_TASK_STACK_DEPTH;
		}
		else
		{
			Jobstate = ' ';
			CmdString[0] = 0;
			JobNumber = 0;
			StackSize = 0;
		}
	}

	CIOCommandOutLine("%-*.*s %2d %c %2d %2d %7ld %6d/%6d  %c %6d %-40.40s", 
		14,
		configMAX_TASK_NAME_LEN-1,
		TaskInfo[TaskIdx].pcTaskName,
		TaskInfo[TaskIdx].xTaskNumber,
		st,
		TaskInfo[TaskIdx].uxCurrentPriority,
		TaskInfo[TaskIdx].uxBasePriority,
		TaskInfo[TaskIdx].ulRunTimeCounter,
		TaskInfo[TaskIdx].usStackHighWaterMark,
		StackSize,
		Jobstate,
		JobNumber,
		CmdString	);

	if ( LockListBuffer[0] != 0 )
		CIOCommandOutLine( " - Locks held: %s", LockListBuffer ); 
}

FreeHeap = xPortGetFreeHeapSize();
CIOCommandOutLine( "Heap Remaining = %u of %u", FreeHeap, configTOTAL_HEAP_SIZE);
CIOCommandOutLine( "Active Job Count = %u", UCL_GetActiveJobCount() );

xTaskResumeAll();

return 0;

}

~~~~~~


Determining optimal stack usage.

Posted by znatok on December 9, 2014

Hi Mark. I do not want to use configUSETRACEFACILITY and uxTaskGetSystemState().

I need access to tasks list but without tracing on as it is costly.

Sent from my iPad

On Dec 9, 2014, at 5:56 AM, "Mark " markwrichardson@users.sf.net wrote:

I did the following . . . The current running job info is application specific, but you should get the idea

//====================================================================== // // notes for below //====================================================================== /* -- TaskStatust type TaskHandlet xHandle - The handle of the task const signed char * pcTaskName - A pointer to the task's name unsigned BaseTypet xTaskNumber - A number unique to the task eTaskState eCurrentState - Task state unsigned BaseTypet uxCurrentPriority - task Priority unsigned BaseType_t uxBasePriority - Normal Priority unsigned long ulRunTimeCounter - Total Run time unsigned short usStackHighWaterMark - smallest stack remaining so far

eTaskState
'G' eRunning = 0,    A task is querying the state of itself, so must be running. 
'R' eReady,          The task being queried is in a read or pending ready list. 
'B' eBlocked,        The task being queried is in the Blocked state.
'S' eSuspended,      The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. 
'D' eDeleted         The task being queried has been deleted, but its TCB has not yet been freed. 

*/

// put here instead of altering the distro void * xTimerGetTimerDaemonTaskHandle( void );

//{ "TASKLIST", "Show all tasks and stats", 0,0, "", { 0 }, 0, 'N', ' ', 's', '=', &cmdTASKLIST }, //====================================================================== // // report task statistics to the console //====================================================================== int cmdTASKLIST( CMDARG *args ) { TaskStatust TaskInfo[1 + TCBASICTASKS + TCMAXJOBTASKS + 1]; unsigned portCHAR TaskCnt; unsigned portLONG TotalRunTime; unsigned portCHAR TaskIdx; portCHAR st; sizet FreeHeap; TASKCTLITEM *pTCI; char CmdString[41]; char Jobstate; CMDJOBNO JobNumber; uint16_t StackSize; char LockListBuffer[100];

vTaskSuspendAll();

TaskCnt = uxTaskGetSystemState( TaskInfo, (1 + TC_BASICTASKS + TC_MAXJOBTASKS + 1), &TotalRunTime);

CIOCommandOutLine("Name           Tn S  P  p RunTime StkRmn/StkSiz St JobNum CmdString");

for(TaskIdx = 0; TaskIdx < TaskCnt; TaskIdx ++)
{
    switch (TaskInfo[TaskIdx].eCurrentState)
    {
        case eRunning:
            st = 'G';
            break;
        case eReady:
            st = 'r';
            break;
        case eBlocked:
            st = 'b';
            break;
        case eSuspended:
            st = 's';
            break;
        case eDeleted:
            st = 'd';
            break;
        default:
            st = '?';
            break;
    };

    pTCI = (TASKCTLITEM *) xTaskGetApplicationTaskTag( TaskInfo[TaskIdx].xHandle );

    if (pTCI)
    {
        if (pTCI->Job )             // JobInfo gets set to zero after Jobstate;
        {
            strncpy(CmdString, pTCI->Job->Args.cmdinput, 40);
        }

        JobNumber = pTCI->Job->JobNo;
        Jobstate = pTCI->JobState;      // get Jobstate after and test in case job ends
        StackSize = pTCI->StackSize;

        if (Jobstate != TC_NOJOB)
        {
            CmdString[40] = 0;
            LockListBuffer[0] = 0;
            RSLMakeListAllDomainLocksForTaskId( pTCI, LockListBuffer );
        }
        else
        {
            // if no job, don't trust job info
            CmdString[0] = 0;       
            JobNumber = 0;
            Jobstate = ' ';
            LockListBuffer[0] = 0;
        }
    }
    else
    {
        if (TaskInfo[TaskIdx].xHandle == xTaskGetIdleTaskHandle())
        {
            Jobstate = ' ';
            CmdString[0] = 0;
            JobNumber = 0;
            StackSize = configMINIMAL_STACK_SIZE;
        }
        else if (TaskInfo[TaskIdx].xHandle == xTimerGetTimerDaemonTaskHandle())
        {
            Jobstate = ' ';
            CmdString[0] = 0;
            JobNumber = 0;
            StackSize = configTIMER_TASK_STACK_DEPTH;
        }
        else
        {
            Jobstate = ' ';
            CmdString[0] = 0;
            JobNumber = 0;
            StackSize = 0;
        }
    }

    CIOCommandOutLine("%-*.*s %2d %c %2d %2d %7ld %6d/%6d  %c %6d %-40.40s", 
        14,
        configMAX_TASK_NAME_LEN-1,
        TaskInfo[TaskIdx].pcTaskName,
        TaskInfo[TaskIdx].xTaskNumber,
        st,
        TaskInfo[TaskIdx].uxCurrentPriority,
        TaskInfo[TaskIdx].uxBasePriority,
        TaskInfo[TaskIdx].ulRunTimeCounter,
        TaskInfo[TaskIdx].usStackHighWaterMark,
        StackSize,
        Jobstate,
        JobNumber,
        CmdString   );

    if ( LockListBuffer[0] != 0 )
        CIOCommandOutLine( " - Locks held: %s", LockListBuffer ); 
}

FreeHeap = xPortGetFreeHeapSize();
CIOCommandOutLine( "Heap Remaining = %u of %u", FreeHeap, configTOTAL_HEAP_SIZE);
CIOCommandOutLine( "Active Job Count = %u", UCL_GetActiveJobCount() );

xTaskResumeAll();

return 0;

} Determining optimal stack usage.

Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/

To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

Attachments

alternate (18684 bytes)

Determining optimal stack usage.

Posted by rtel on December 9, 2014

uxTaskGetSystemState() is the function provided to do this. If you don't want to use that function then I'm afraid the only way is to provide your own, which will mean adding your own code to the FreeRTOS tasks.c file. You can copy the way uxTaskGetSystemState() does it, but if you are going to copy the way it does it, it would seem to make sense to instead edit tasks.c to just remove the need for configUSETRACEFACILITY to be defined.

FreeRTOS has always employed strict data hiding as a principal of good engineering practice, so without adding your own code into tasks.c, or using the API function already provided to do this, there is no other way as that is the only file in which the information you need is accessible.

Regards.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS