6 misconceptions about the RTOS tick
This article is written by Jean J. Labrosse, RTOS Expert.
Nearly every RTOS is equipped with a time source, generally provided by a hardware timer that interrupts the CPU at a certain rate (called the Tick Rate) which is generally chosen to be between 10 and 1000 Hz; with 1000 Hz being the most common. This dedicated RTOS timer is called a Clock Tick, System Tick or, RTOS Tick. The higher the Tick Rate, the higher the overhead the RTOS will impose on your system.
This time source is used to delay (i.e. sleep) tasks a certain amount of time and, provide timeouts on APIs that are invoked by tasks that are waiting for events to occur. The higher the Tick Rate, the better the resolution of time delays and timeouts (up to a certain point). For example, a task could decide to wait for an ethernet packet to arrive but, only willing to wait up to a certain amount of time, thus the timeout.
The pseudo-code snippet below shows how a time delay (i.e. sleep) RTOS service can be used in a task. The code in Red indicates an RTOS API. One thing to note is that if you want to delay a task for 1 tick (i.e. 1 millisecond if the Tick Rate is 1000 Hz) then you might need to specify 2 ticks! The reason is that the CPU can only run one task at any given time and, if this is a low priority task, it might end up running just before the next tick arrives which would cause the task to potentially run again immediately. If you needed to have that 1 millisecond delay then you might in fact end up with no delay at all!
void Task (void)
{
// Task initialization
while (1) {
Delay(#ticks);
Perform some periodic work;
}
}
The following pseudo-code shows how a task can wait for an event (ADC conversion, ethernet packet, etc.) and specify a timeout. In this case, the timeout is used to avoid waiting forever for the event to occur. The timeout could indicate a failure in hardware or could be an expected outcome.
void Task (void)
{
OS_ERR err;
// Task initialization
while (1) {
err = WaitForEvent(&EventObject, timeout);
if (err == TIMEOUT_OCCURRED) {
Event didn’t happen within timeout;
} else {
Event occurred, process;
}
}
}
Misconception #1: The RTOS Tick is the scheduler
An RTOS runs the scheduler whenever an event occurs which typically causes the RTOS to determine if a more important task needs to run. The Tick interrupt (i.e. event) is just one of many events in an RTOS-based system that causes the scheduler to run! So, if an ethernet packet arrives and that is the event that a task is waiting for then the RTOS will determine if it should run that task immediately after the ISR (for the ethernet) returns.
Misconception #2: The RTOS Tick is always necessary with an RTOS
Although most RTOS do indeed need a Clock Tick, if your application never puts a task to sleep or, never uses timeouts then, you could simply omit it from your system! Of course, you need to make sure that you really don’t use this functionality (RTOS ticks) because otherwise tasks will not behave as you expect them to. If you are not sure, just enable the RTOS Tick.
Misconception #3: The RTOS Tick interrupt must be the highest priority
This is absolutely not true and in fact, I could make the case that it should be one of the lowest priority interrupts in your system and if not, certainly lower than your application’s real-time interrupts. You most likely want to put more importance on sampling of analog inputs, controlling a high-speed motor, responding to TCP/IP traffic, etc. The RTOS Tick is meant for coarse time delays and timeouts.
Misconception #4: The RTOS Tick Rate must be accurate
Again, the whole purpose of the tick is to provide coarse time delays and timeouts. If your application requires a very accurate periodic interrupt then, you should use a separate timer and make its interrupt a high priority.
Misconception #5: The Clock Tick must be dedicated to the RTOS
It’s generally true that when you assign a hardware timer to the RTOS, it is used for time delays and timeouts but, in some cases, you might want to intercept the timer interrupt and perform some operations before you have the RTOS perform its function. Specifically, some RTOS (like uC/OS-III) allow you to call a user defined function (i.e. a hook, a.k.a. a callback) before calling the RTOS tick services. The pseudo-code looks as shown in the snippet below.
RTOS_TickISR(void)
{
Call user defined function; // i.e. a hook (a.k.a. callback)
Call the RTOS tick services;
}
You would want to use this feature if you are short on hardware timers and/or want to have a fairly accurate time source. Calling your code before the RTOS will ensure that it will not be subject to task jitter that is caused by the RTOS scheduler.
Misconception #6: You always need a hardware timer
Again, if you are short on hardware timers and your embedded system is powered by an AC power source then, you could simply extract the line frequency (your hardware Engineer will need to get involved) and get 50 or 60 Hz (depending on the country) or, detect zero crossings of the power line thus obtaining double the frequency (100 or 120 Hz). It turns out that, at least in the US, the long-term accuracy is relatively stable and accurate. Therefore, AC powered electrical wall clocks are quite good at keeping time.
About the author
This article is part of a series on the topic of developing applications with RTOS.
Jean Labrosse, Micrium Founder and author of the widely popular uC/OS-II and uC/OS-III kernels, remains actively involved in the evolution of the uC/ line of embedded software.
Given his wealth of experience and deep understanding of the embedded systems market, Jean serves as a principal advisor and consultant to Weston Embedded Solutions helping to chart the future direction of the current RTOS offerings. Weston Embedded Solutions specializes in the support and development of the highly reliable Cesium RTOS family of products that are derived from the Micrium codebase.
You can contact him at Jean.Labrosse@Weston-Embedded.com.