CPU use stat advice

ldb wrote on Thursday, November 08, 2018:

I added CPU load to FreeRTOS by incrementing a counter each CPULoad timertick if and only if the current task is the idle task. I then run a 1 sec task that reads the count and then zeros the value , from the read value

CPU load = (configTICK_RATE_HZ - CPULoad timertick) / configTICK_RATE_HZ * 100;

Pretty obvious:
If you have 1000 ticks per second and all 1000 ticks are idle you have 0% load
If you have 1000 ticks per second and 0 ticks are idle you have 100% load

Anyhow all works easily and it means in the timer interrupt I need to pick off if the current task is the Idle task. The interrupt handler also means I know its safe to play with pxCurrentTCB.

At the moment I have this naft bit of code

if ((pxCurrentTCB) &&
		(pxCurrentTCB->pcTaskName[0] == 'I') &&
		(pxCurrentTCB->pcTaskName[1] == 'D') &&
		(pxCurrentTCB->pcTaskName[2] == 'L') &&
		(pxCurrentTCB->pcTaskName[3] == 'E'))
	{

Is there any other obvious way to pick the idle task or should I just jam a flag in the TCB struct and set it when I create the idle task?

rtel wrote on Thursday, November 08, 2018:

There is a function to get the idle task’s handle, which you can then compare directly with pxCurrentTCB, not at my computer right now otherwise I would send a link.

Likewise there is a facility to measure the percentage of cpu time each task uses, you just have to provide a high frequency time source.

Will your method, which is lighter weight, take into account that task’s switch in and out between tick interrupts too? The idle task might count when it only ran for a fraction of a tick, or not count when it ran for most but not all of a tick period.

ldb wrote on Thursday, November 08, 2018:

Update: Okay got it doing the CPU load calc automatically and smooth didnt even need task and its pretty neat and very low on CPU cycles … but open to improvement/suggestions

Works pretty neat at any time I can get the CPU load for little overhead but would love easier pick of idle :slight_smile:

PRIVILEGED_DATA static volatile unsigned int uxPercentLoadCPU					= (unsigned int) 0U; // Last CPU load calculated
PRIVILEGED_DATA static volatile unsigned int uxIdleTickCount					= (unsigned int) 0U; // How many ticks were in idle task
PRIVILEGED_DATA static volatile unsigned int uxCPULoadCount						= (unsigned int) 0U; // For 0 to configTICK_RATE_HZ we will count idle tasks

/* Function to read the last calculated load .. interfaced on Task.h */
unsigned int xLoadPercentCPU (void)
{
	return uxPercentLoadCPU;
}

/* In the top of where the timer tick enters */
void vTaskIncrementTick( void )
{
tskTCB * pxTCB;
	
    if ((pxCurrentTCB) &&
		(pxCurrentTCB->pcTaskName[0] == 'I') &&
		(pxCurrentTCB->pcTaskName[1] == 'D') &&
		(pxCurrentTCB->pcTaskName[2] == 'L') &&
		(pxCurrentTCB->pcTaskName[3] == 'E'))
	{
		uxIdleTickCount++;
	}
	uxCPULoadCount++;
	if (uxCPULoadCount == configTICK_RATE_HZ)
	{
		uxCPULoadCount = 0;
		uxPercentLoadCPU = (configTICK_RATE_HZ - uxIdleTickCount) * 100 / configTICK_RATE_HZ;
		uxIdleTickCount = 0;
	}

rtel wrote on Thursday, November 08, 2018:

Here are a couple of links relevant to my last post, that I could get at
the time of writing that post.

https://www.freertos.org/a00021.html#xTaskGetIdleTaskHandle
https://www.freertos.org/rtos-run-time-stats.html

In addition, if you would like to add your own code into the increment
tick function then you can do so without needing to edit the source code
by defining traceTASK_INCREMENT_TICK() in FreeRTOSConfig.h to
call/include your code.

https://www.freertos.org/rtos-trace-macros.html

ldb wrote on Thursday, November 08, 2018:

Yeah I saw those but they are slow and I am not sure you can call from inside the IRQ handler.
I end up moving the calc to the get value API code, just so the mult and divid were not in the IRQ handler even if it only happens once a second. So I hold just the raw last idle tick count every 1 second, if you ask for the CPU load then it does the maths. It works pretty sweet.

I think I will just tag a field into the TCB it 1 byte and saves all the compares, especially since I have that nice little flag idea you suggested.

ldb wrote on Friday, November 09, 2018:

Sorry last part of this … I just have a quick question

I decided I should update to latest version 10 and no real issue was easy to implement again but I noticed

“vTaskIncrementTick” is now called “xTaskIncrementTick”

What is the significance of the v and x at start?

richarddamon wrote on Friday, November 09, 2018:

The return type, v is void, x is basically an int. It now returns a flag to indicate that a context switch should happen (I think this change occuered a while back),

rtel wrote on Friday, November 09, 2018:

The change in return type was an optimization, preventing unnecessary context switches. https://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html