Determining optimal stack usage.

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.

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.

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.

https://sourceforge.net/p/freertos/discussion/382005/thread/f3164f7d/?limit=25#cb43

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.

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 ) { TaskStatus_t TaskInfo[1 + TC_BASICTASKS + TC_MAXJOBTASKS + 1]; unsigned portCHAR TaskCnt; unsigned portLONG TotalRunTime; unsigned portCHAR TaskIdx; portCHAR st; size_t 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.

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 ) { TaskStatus_t TaskInfo[1 + TC_BASICTASKS + TC_MAXJOBTASKS + 1]; unsigned portCHAR TaskCnt; unsigned portLONG TotalRunTime; unsigned portCHAR TaskIdx; portCHAR st; size_t 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/

Determining optimal stack usage.

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.