Task Execution Time
Thought I would share a change I made to the CTL.
The CTL has a mechanism to measure the time each task has been running. It's track in variable execution_time within the TCB.
Problem is that the data it records can be very misleading as it simply calculates task time running by using the CTL clock which has a resolution of 10 msec.
The current time is tracked in my CTL implementation has a count resolution of 1 millsec but the TicTimer is set for 10 millsec. Each time the TicTimer fires, current time is update by 10 --- the CTL's time resolution.
I use multiple tasks that sleep and become active via the following: ctl_timeout_wait(ctl_get_current_time()+10); The task wakes up, does its work and waits for the stated time.
The current CTL execution timing mechanism simply subtracts two times -- and most of the time they are the same time value because the task awakes and sleeps within the same 10 millisec window --- so time is measured as zero. The execution time error can approach 20 millisec depending on when the task awakes and sleeps in relation to when the TicTimer fires and the task's priority.
I added a "debug" mechanism to the CTL. My code is defined in or out based on debug defines, etc.
I added another function that works in conjunction with the TicTimer.
#define ONE_MICROSEC (SystemCoreClock/SYSTICKDIVIDER/1000000)
This determines the number of timer tics that equate to 1 microsec.
byte TicIntFlag = 0; // helps to keep insync with timer int. It's a flag to tell me if the TicTimer fired while I was computing time
unsigned long Get_Hinkle_1MicroSec_clock(void)
{
dword CT;
unsigned long V;
TicIntFlag = 0;
V = (SysTick->LOAD+1) - SysTick->VAL; // timer is count down so this gives tic used
V /= ONE_MICROSEC;
CT = (ctl_current_time * 1000) + V; // current time is in units of millisec
if(TicIntFlag) // clock has been update while we were here --- so fix
{
V = (SysTick->LOAD+1) - SysTick->VAL; // timer is count down so this gives tic used
V /= ONE_MICROSEC;
CT = (ctl_current_time * 1000) + V;
}
return CT
}
TicIntFlag is set to 1 in the TicTimer interrupt
This is the additional function. It calculates the current time in microseconds. If a TicTimer INT occured - it is recalculated.
The change to the CTL is associated with the function ctl_private_reschedule()
The two lines are the unchanged CTL lines of code
ctl_task_executing->execution_time += ctl_current_time - ctl_last_schedule_time;
ctl_last_schedule_time = ctl_current_time;
The following is what I changed
dword TT;
TT = Get_Hinkle_1MicroSec_clock();
ctl_task_executing->execution_time += TT - ctl_last_schedule_time;
ctl_last_schedule_time = TT;
The change is not meant to EXACTLY track execution time to the microsec but the time resolution now allows a good time comparisons between tasks when their performance is being analyzed and tuned.
Since your execution_time variable is a DWORD --- it can track microsec times for 71 minutes before it rolls over -- well within my testing window.
Please sign in to leave a comment.
Comments
0 comments