Run Time Statistics for msp430 f5438

modiallen wrote on Wednesday, July 11, 2012:

Hi everyone,
i read the documentation about the Run Time Statistics, and i didnt understand everything about it.
is there an already existing implemented timer for this macro portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(), or should i make it by my self and how to implement it.

because there is no example how to implement the timer for it.

Regards,
Mhd

edwards3 wrote on Wednesday, July 11, 2012:

All you need is a time source that is fast enough. It has to be a lot faster than the tick interrupt for stats with a good resolution. How the time source is generated is very dependent on the peripherals that are available on your chip so you will need to configure that yourself.

modiallen wrote on Thursday, July 12, 2012:

thank you for your reply.
can you give me more details about how to implement this.

rtel wrote on Thursday, July 12, 2012:

We cannot provide support on using MSP430 specific hardware timers, but the macros and functions that need to be implemented, along with a couple of examples for other architectures, is provided here:

http://www.freertos.org/rtos-run-time-stats.html

… although I presume you have seen that already.  You can also search the FreeRTOS/Demo directory for other examples of where the macros portCONFIGURE_TIMER_FOR_RUN_TIME_STATS and portGET_RUN_TIME_COUNTER_VALUE are used.

Regards.

modiallen wrote on Friday, July 13, 2012:

Hi Richard,
my questions were not about the direct implementation. but i am asking to have more information than the information in the descrition.

like: where should the macro vTaskGetRunTimeStats() be called? in every task or only one time in one task and it will gather the statics about every other task?

from desciption in this site:   http://www.freertos.org/rtos-run-time-stats.html
i understand that this macro must be used to configure the timer only but in the first example it was used to set the variable to 0 and the other macro portGET_RUN_TIME_COUNTER_VALUE to get the value of this variable. that is why, i am a little confused.

thanks for your reply.

rtel wrote on Friday, July 13, 2012:

where should the macro vTaskGetRunTimeStats() be called?

That function is used to generate a human readable table of gathered run time stats.  You can call it from any task that needs this information.  It is normally used to output the information to a web server or console for viewing by the user.

or only one time in one task and it will gather the statics about every other task?

vTaskGetRunTimeStats() does not gather the statistics, it only formats them into a human readable table.  The kernel itself gathers the run time statistics if configGENERATE_RUN_TIME_STATS is set to 1.  If configGENERATE_RUN_TIME_STATS is set to one then the kernel tries to call portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() once during start up, then portGET_RUN_TIME_COUNTER_VALUE() on each task switch.  That is why you have to define the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() portGET_RUN_TIME_COUNTER_VALUE() to do the right thing for your hardware (you define them, but you don’t call them, the kernel calls them).

i understand that this macro must be used to configure the timer only but in the first example it was used to set the variable to 0 and the other macro portGET_RUN_TIME_COUNTER_VALUE to get the value of this variable. that is why, i am a little confused.

vTaskGetRunTimeStats() does not set anything to zero, in the example portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() sets a variable to zero (for that particular implementation) because it is called once at start up it does the initialisation.  The other macro returns the value because it is called during a context switch to return the current time value.

Hope that helps.
Regards.

ulmus71 wrote on Friday, July 13, 2012:

modiallen, it is so simple…  vTaskGetRunTimeStats() is called once if you want have stats.
portGET_RUN_TIME_COUNTER_VALUE must return counter value that is 10 to 100 quicket than FreeRTOS ticks. In example on the site you mentioned is a timer register, thats why it is just variable simple macro. In my implementation it is a variable too, but in configure function i am configuring hardware timer which increment that variable with proper frequency, to get good stats…

ulmus71 wrote on Friday, July 13, 2012:

Sorry for my answer, link to post showed me only one post :smiley: i havent seen your answers:):slight_smile:

modiallen wrote on Saturday, July 14, 2012:

thank you a lot richard. now i got it.
i implemented it like this:
i implement a timer that will cause an interrupt 10 times faster than the interrupt from the scheduler. and increment a variable every time this interrupt occured. and the macro  portGET_RUN_TIME_COUNTER_VALUE only return the value of this variable.

i think now it must work. but i am getting nonreasnoble stats now.
all tasks have the absolut time “u” or the percentage values “u” %.
what does this “u” mean here?

ulmus, thank you for your answer.

modiallen wrote on Wednesday, July 18, 2012:

Hi,
as i told the last time, the Statistics, that i am getting are only “u”  for almost every task except the idle task.
what does this “u” mean? undefined?

edwards3 wrote on Wednesday, July 18, 2012:

It probably just means that your C library does not understand the %u format specifier, so just prints the u out. Look at the code:

						#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
						{
							sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage );							
						}
						#else
						{
							/* sizeof( int ) == sizeof( long ) so a smaller
							printf() library can be used. */
							sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
						}
						#endif

edwards3 wrote on Wednesday, July 18, 2012:

Try again with different formatting:

#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
    sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", 
            pxNextTCB->pcTaskName, 
            pxNextTCB->ulRunTimeCounter, 
            ulStatsAsPercentage );                            
}
#else
{
    /* sizeof( int ) == sizeof( long ) so a smaller
    printf() library can be used. */
    sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", 
            pxNextTCB->pcTaskName, 
            ( unsigned int ) pxNextTCB->ulRunTimeCounter, 
            ( unsigned int ) ulStatsAsPercentage );
}
#endif

modiallen wrote on Thursday, August 02, 2012:

hey,
thank you for your reply.
the compiler must be configured to support printf to get the values. but i cannot do it due to the limited size that i have now in my application. i am reading it manually with the support of breakpoints.