Before you establish the priority of tick handling in your system, it’s important to note that tick-related delays, as my last post indicated, might not always be the best way to implement periodic behavior in your system. One reason that you may wish to avoid relying on ticks in certain tasks is that the delays tend to fluctuate from call to call. If one of your system’s tasks repeatedly calls OSTimeDly() for a five-tick delay, and the tick period for your system is 1 ms, the task won’t always remain in the waiting state for exactly 5 ms. In some cases, it may experience a delay closer to 4 ms, while in others, it may remain delayed for 6 ms or more.
In many systems, one of the causes of this fluctuation, or jitter, is the use of delay functions by multiple tasks. As Figure 1 illustrates, if the delay periods for three tasks all expire on the same kernel tick, then only the highest priority of those tasks will run immediately after the tick handler. Over time, the lower priority tasks will experience much more jitter in their delays, since the possibility always exists that they won’t be able to run immediately following the tick that moves them to the ready state.
Of course, variability in the tick handler priority presents another potential source of delay fluctuation. In the example of µC/OS-III, which sets aside a system task for processing tick interrupts, if this task is given a relatively low priority and a tick occurs while a high-priority task is running, then the kernel won’t be able to process the tick and perform any related scheduling until the CPU is relinquished by the high-priority task, as shown in Figure 2. In µC/OS-II, which handles ticks entirely in an ISR, a similar situation could occur if this ISR were given a relatively low priority and a tick occurred during the execution of a more important ISR.
In setting your tick priority, you’ll need to keep in mind your application’s tolerance for fluctuating delays. If your code can accommodate fluctuations of several milliseconds – perhaps because you’ll be using tick delays only to poll user I/O – then you can opt for a relatively low-priority tick. On the other hand, if your tasks require fairly consistent delays, then you should employ a high priority, and you should also take measures to limit the number of tasks that use delay functions.
The flexibility that RTOS kernel users may have in configuring tick priority and frequency can certainly lead to some difficulties for developers who are new to the kernels. However, with information on the tradeoffs involved in setting up the tick, this flexibility becomes an invaluable means of tailoring multi-task systems to meet the needs of a variety of applications. I’ve attempted to provide a few of the key pieces of information needed for tick use and configuration in this series of blogs. For additional details on kernel ticks, some good sources of information are the µC/OS-II and µC/OS-III books.
Matt Gordon is a senior applications engineer at Micrium. He began his career developing device drivers, kernel ports, and example applications for Micrium’s customers. Drawing on this experience, Matt has written multiple articles on embedded software. He also heads Micrium’s training program and regularly teaches classes on real-time kernels and other embedded software components. Matt holds a bachelor’s degree in computer engineering from Georgia Institute of Technology, Georgia.