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 theconfigUSETRACEFACILITY 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*/ // 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];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.
} 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/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.
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.