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
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.
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.
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
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;
}
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.
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.
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),