Reset RunTimeStats

preetpal wrote on Wednesday, February 10, 2010:

I’m an advanced user of the FreeRTOS, however, I can’t seem to reset the runtime counters.  Resetting the counters is important in applications where the tasks are resumed or suspended upon events so you can measure runtime stats during IDLE and LOAD conditions separately.

I modified vTaskGetRunTimeStats() which takes a boolean to reset the counters, and prvGenerateRunTimeStatsForTasksInList() resets the ulRunTimeCounter for each task based on this boolean variable.  Then at the end of vTaskGetRunTimeStats(), it resets the ulTempCounter and the high-frequency hardware timer values to zero before returning.

It all seems to be working well for all tasks, except for the task that is calling vTaskGetRunTimeStats.  Somehow, the task calling the function ends up having a rather corrupt value of its ulRunTimeCouter even though the ulRunTimeCounter was reset.   I am using interrupt driven serial communication so the task calling vTaskGetRunTimeStats() is not getting blocked while delivering UART data, it suspends immediately after calling vTaskGetRunTimeStats().  Upon entry to vTaskGetRunTimeStats(), the scheduler is suspended, so it should not add anything to ulRunTimeCounter of any task.  sprintf should concatenate the data and when vTaskGetRunTimeStats() exits, before resuming the scheduler, all counters should be zero… but somehow something appears to be wrong somewhere…

Any hints anyone?  Richard?  I am willing to help implement this method for future versions and it is almost done, except for the issue mentioned above.  Source code is well organized too and I only added one more macro other than boolean parameter to vTaskGetRunTimeStats(): portRESET_RUN_TIME_COUNTER()

Thanks in advance,

rtel wrote on Wednesday, February 10, 2010:

I’m not sure I fully follow here, but my first question is are you re-initialising ulTaskSwitchedInTime?  I presume that should get set back to zero, or whatever the current ‘time’ is too.


preetpal wrote on Wednesday, February 10, 2010:

Ahh… I figured out the problem.  One of the Timer1 registers said it would reset the Counter but it wasn’t doing exactly that.  Since the counter was not reset, the task calling vTaskGetRunTimeStats() was recording all the counter value to the tasks’ runtime counter when it got switched out.

I would recommend the following changes and I can provide the code if you’d like:
1.  Modify vTaskGetRunTimeStats() and prvGenerateRunTimeStatsForTasksInList() to take bool resetCounters as parameter
2.  prvGenerateRunTimeStatsForTasksInList() should resert ulRunTimeCounter for each task if resetCounters is true
3.  vTaskGetRunTimeStats() should call portRESET_RUN_TIME_COUNTER(); and set ulTaskSwitchedInTime = 0UL; before xTaskResumeAll()

That will enable users to reset counters to measure the system load in relative terms.  One more thing I added in my case is that prvGenerateRunTimeStatsForTasksInList() returns total runtime of the tasks.  vTaskGetRunTimeStats() adds all the values together and subtracts from ulTotalRunTime.  That can allow users to measure the overhead(OS overhead or ISR overhead) using the following code:

unsigned int overheadTime = ulTotalRunTime - runTimeCounterOfAllTasks;
sprintf( pcStatsString, ( char * ) “%16s  %10u  %3u%%\r\n”, “<OVERHEAD>”, overheadTime, (unsigned int)((overheadTime*100)/ulTotalRunTime) );
strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );

Thanks for the help!  I struggled with this problem for many hours and finally figured it out yesterday by going back to the basics.