Page 1 of 2
"Task Manager" for RTOS?
Posted: Tue Oct 15, 2013 12:16 pm
by rlupish
We've implemented a communications interface using the MOD54415, receiving data via 2 of the UARTs, processing it and sending it out via other serial and network ports. Currently has about about 14 tasks running asynchronously, hopefully prioritized correctly. TICKS_PER_SECOND set at 100.
I need to know whether we're anywhere near close to running out of machine cycles (unlikely, but we'd like some quantitative data to back that up). Ideally, a utility we could run like the Windows task manager, showing CPU usage and accumulated time per task, would do the trick. The "clock()" function would be ideal, if per documentation it returns "the processor time used by the program since the beginning of execution" (K&R) and "program" is interpreted as "task". Let the system run for a while, then displaying accumulated per task times (plus total elapsed time) would give me what I need. (However, trying to build with the clock() function results in the "undefined reference to 'times'" problem, documented elsewhere (but not resolved) in the forum.)
Maybe I missed something in the documentation, but I couldn't find anything to accumulate run-time ticks on a per-task basis.
Any ideas?
Re: "Task Manager" for RTOS?
Posted: Tue Oct 15, 2013 4:55 pm
by tod
I would think you could write something pretty easily that gives you a good approximation. Increment a counter in an otherwise empty app for x number of ticks. Here's a first pass
(no warranty (implied or otherwise) or guarantee of fitness for any purpose):
Code: Select all
const int FOREVER =1;
const int MAX_TICKS_FOR_TIMING_TEST=20 *TICKS_PER_SECOND;
bool running_test = true;
int start_tick = TimeTick;
long long int counter = 0;
while (FOREVER)
{
if (!running_test)
{
OSTimeDly(TICKS_PER_SECOND);
cout << ".";
}
else
{
++counter;
int elapsed_ticks = TimeTick - start_tick;
if (elapsed_ticks > MAX_TICKS_FOR_TIMING_TEST)
{
running_test = false;
double secs = elapsed_ticks/TICKS_PER_SECOND;
double counts_per_sec = static_cast<double>(counter)/secs;
cout << "Counts per second in empty app:"<< counts_per_sec << "\n";
}
}
}
(BTW, this gives me about 35.79 million counts/sec). Then copy similar code over to your actual app and put it in a new lowest priority task. Calculate your counts as a pct of the baseline and output the percentage however often you want. Then you could lower TICKS_PER_SECOND back to 20 and see if that generates significant CPU savings.
Regarding the undefined reference to times, I always assumed that meant that some standard C header defines a function that was not actually ported over for the hardware (i.e never implemented). The header makes a promise to the linker and the linker gets upset when the promise is broken.
Re: "Task Manager" for RTOS?
Posted: Wed Oct 16, 2013 1:43 pm
by rlupish
Thanks Tod,
I followed your excelent suggestion, and got reasonable numbers for CPU usage (compared to baseline) of the overall systems under various "loads".

I got a "no load" (baseline) rate of about 41.6*10^6 increments (and compares) per second on the MOD54415, FYI.
Found a few interesting side things in the process:
1) Lib functions (iprintf, SysLog, others?) i/o formatting doesn't know how to handle long long ints with either %d or %ld - ended up having to just use counter defined as "just" a long int, which, at 32 bits was enough for about 50 seconds worth of data without overflowing.
2) iprintf formatting doesn't even understand %f format - printed just "f". SysLog with same format displayed just fine!
Ron
Re: "Task Manager" for RTOS?
Posted: Wed Oct 16, 2013 1:48 pm
by rnixon
Hi Ron. The 'i' in iprintf() means integer only. The advantage is you don't link in all the floating point stuff so you app is smaller.
Re: "Task Manager" for RTOS?
Posted: Wed Oct 16, 2013 3:35 pm
by tod
I really shouldn't say this (because it just encourages continued use of printf) but %lld (two ls and a d) should work for printf and long longs. I might even work for iprintf - but no promises because it isn't named lprintf or even llprintf .
Re: "Task Manager" for RTOS?
Posted: Wed Oct 16, 2013 4:23 pm
by dciliske
Ask and you shall receive: we have now added the ability to log task times in UCOS (via library macro, of course). This is kinda tightly coupled with the OS, (what with modifying the scheduler to stamp things) so I'm not certain about trying to give the patched files or just wait for the next beta.
It adds two functions to ucos.h:
ShowTaskTimes() - Print task list and running times to std out
ClearTaskTimes() - clears the elapsed times for all tasks (hmmm... maybe this should be ResetTaskTimes?)
Sample output:
uc/OS Tasks
Name Prio TotTicks %
Idle | 63 | 8650 | 55
Main | 50 | 96 | 0
TCPD | 40 | 0 | 0
IP | 39 | 4650 | 30
Enet | 38 | 2052 | 13
HTTP | 45 | 2 | 0
-Dan
Re: "Task Manager" for RTOS?
Posted: Wed Oct 16, 2013 4:49 pm
by Ridgeglider
This is a great addition Dan. Thanks!
Re: "Task Manager" for RTOS?
Posted: Wed Oct 16, 2013 4:52 pm
by Ridgeglider
Is there a hook so that a task can easily monitor it's task time w/o dumping the output?
IE, something like:
if ( MyPercentTaskTime > MyTaskTimeLimit ) {
HandleError();
}
Re: "Task Manager" for RTOS?
Posted: Thu Oct 17, 2013 4:38 am
by rlupish
Way cool addition, Dan.
Looking forward to next beta release to incorporate!
Thanks!
Re: "Task Manager" for RTOS?
Posted: Thu Oct 17, 2013 11:22 am
by dciliske
Ridgeglider: Wow that was easy. Probably a useful function too
The support API for the functionality is:
Code: Select all
uint32_t GetCurrentTaskTime( uint32_t *TotalTicks );
void ShowTaskTimes();
void ClearTaskTimes();
GetCurrentTaskTime takes a pointer to a variable to write the total timed ticks (which may differ from TimeTick). It returns the value of the current task's runtime. The reason for having TotalTicks returned via pointer and not a second function is so that both values are calculated in the same critical section, ensuring coherent data.
Any other requests?
-Dan