COMATOS uses Timer 0 as a system clock, which maintains a 1 ms time base. The Timer 0 ISR updates the various clocks used by the system to schedule tasks and to check for errors. As a result, Timer 0 is not available to user programs. Because the Timer 0 interrupt-on-overflow feature MUST be left on at all times, take care not to disable it when manipulating Timer 1 via the TIMSK register.
The clock divider is set to 8. At each interrupt, the value of 6 is loaded into the timer, leading to a count of 250 between interrupts. These values result in an interrupt every 0.5 ms. However, the functions of a timer tick are only performed every 1ms. The t0ms bit in the OSStatus register indicates whether the current interrupt represents a full-millisecond or a half-millisecond. A value of 1 indicates that the next interrupt will be a full-millisecond, whereas a 0 signifies that the coming interrupt will be on a half-millisecond.
The system clock is accurate to approximately 1%. While this accuracy is adequate for most scheduling functions, timer 1 should be used for any extremely accurate timing purposes.
The system clock's main purpose is to increment/decrement the various time dependent counters in the OS. Below is a list of the various functions performed by the timer 0 ISR every millisecond.
The only error caught by the system clock is a system timeout, in which a task has failed to return within the time allotted by OSMaxTimeout. Because COMATOS is a non-preemptive operating system, in which tasks are not interrupted, the failure of a task to return constitutes a fatal error. In a real-time system, every task is generally critical; so, the system is halted when a task fails. The following functions are performed when the system times out.
The ISR is run every 0.5ms, introducing significant overhead, which reduces the throughput of the MCU. In applications for which speed is vital, this overhead must be taken into account. Table 1 illustrates the cycle overhead for the various components of the ISR.
|Table 1: System Clock Overhead|
|Component of clock||Cycles|
|Run during every interrupt (0.5 ms)|
|Run on the half-millisecond|
|Check t0ms bit, set it if cleared, return||25|
|Run on the full-millisecond|
|Check t0ms bit, clear it if set||24|
|Increment global time||22|
|Set up task loop||7|
|Decrement PCBCurrentTime for a single task, if appropriate. Will be done for each task.||12|
|Check for task failing to return on time (while a task is running)||21|
|Check for task failing to return on time (while no task is running)||7|
|Percentage of CPU time devoted to system clock (depends on number of tasks)||2.8% - 5.5%|
(4.2% for 3 tasks)