Task Switching and Time Keeping
Here you'll learn all about the timeslice clock and how to use it. As well as providing an elapsed time clock, the timeslice clock is used to guarantee the timeliness of pre-emptive task switching. Understanding its use will enable you to write fast, responsive C language programs to provide real-time control of your instrument.
The built-in elapsed time clock
The QCard Controller is a Single Board Computer (SBC) with a built-in multitasking executive that maintains an elapsed time clock whenever the timeslicer is active. Please consult the TIMEKEEP.C program in the \MOSAIC\DEMOS_AND_DRIVERS\MISC\C EXAMPLES
directory for examples of using the elapsed time clock.
You control the timeslice clock with the following functions:
- StartTimeslicer()
- TIMESLICE_COUNT
- ChangeTaskerPeriod()
- InitElapsedTime()
- ReadElapsedSeconds()
Your program can start the timeslice clock by calling the function:
StartTimeslicer()
The timeslicer increments the long variable named TIMESLICE_COUNT each timeslice period. The default timeslice period is 5 milliseconds (ms), and this can be modified by calling
ChangeTaskerPeriod()
as described in the Control-C Glossary. The function
InitElapsedTime()
sets TIMESLICE_COUNT equal to zero. The function
ReadElapsedSeconds()
returns a long result representing the number of elapsed seconds since InitElapsedTime() was called.
To attain the full 5 millisecond resolution of the elapsed time counter, we can write a simple function that converts the TIMESLICE_COUNT into elapsed seconds as well as the number of milliseconds since the last integral second. For example, let’s examine some code from the TIMEKEEP.C
file in the \MOSAIC\DEMOS_AND_DRIVERS\MISC\C EXAMPLES
directory:
#define DEFAULT_TIMESLICE_PERIOD 5 // {ms}; system default #define MS_PER_SECOND 1000 static long start_time; // saves starting count of TIMESLICE_COUNT _Q void MarkTime(void) { start_time = FetchLongProtected( (xaddr)((unsigned)(&TIMESLICE_COUNT)) ); } _Q void PrintElapsedTime(void) { long elapsed_ms = DEFAULT_TIMESLICE_PERIOD*(FetchLongProtected( (xaddr)((unsigned)(&TIMESLICE_COUNT)) ) - start_time); long seconds = elapsed_ms / MS_PER_SECOND; int ms_after_second = elapsed_ms % MS_PER_SECOND; printf("\nTime since mark is: %ld seconds and %d ms.\n", seconds, ms_after_second); }
The MarkTime()
function simply stores the TIMESLICE_COUNT
in the start_time
variable. The timeslicer is continually incrementing its counter, and when you later call PrintElapsedTime()
, start_time
is subtracted from the latest TIMESLICE_COUNT
and multiplied by the timeslice period to calculate the elapsed number of milliseconds. This is converted into the elapsed seconds by dividing by 1000, and the remainder is the number of milliseconds since the last integral elapsed second.
To try it out, use the Mosaic IDE’s editor to open the TIMEKEEP.C
file in the \MOSAIC\DEMOS_AND_DRIVERS\MISC\C EXAMPLES
directory, click on the Make Tool to compile the program, and use the terminal to send TIMEKEEP.DLF
to the QCard. At your terminal, type:
main
to start the timeslicer and initialize the program. Now at any time you can mark a starting time by typing at the terminal:
MarkTime( )
and you can print the elapsed seconds and ms since the last mark by typing:
PrintElapsedTime( )
which will produce a response of the form:
Time since mark is: 3 seconds and 45 ms.