The scheduler of all RTOSes, from the 1980s to today, works with a system tick, which is the basic time unit. So every time specification is given in multiples of ticks, where users can configure the distance between these ticks individually, usually for example to 1 millisecond. This then means that a hardware timer is programmed to generate an interrupt 1000 times per second, indicating the expiration of one millisecond each time. Although 1 millisecond already sounds high-resolution and fast, there was still a need for improvement given the requirements of modern embedded systems.
embOS-Ultra's revolutionary clock-cycle-based scheduling changes the fundamental time unit of the system, dramatically increasing the resolution of the scheduling. Instead of relying on the traditional system tick, embOS-Ultra internally uses clock cycles for all operations. Time-based operations such as for task delays or software timers, which previously could only be specified in multiples of ticks, can now be specified in clock cycles as a result. In addition, users of embOS-Ultra can now use system-independent, high-resolution units such as microseconds or even nanoseconds for time-based operations in one and the same application instead of just system ticks.
The cycle resolution scheduling of embOS-Ultra brings two decisive advantages to the developer: Higher precision and lower energy consumption. First, temporal sequences become more accurate.
In most RTOSes, for example, a Delay(5) will interrupt the operation of the corresponding thread for a time between 4 and 5 milliseconds – depending on how far away the next tick of the system is. Why is this? A programmed delay cannot end between two system tick interrupts, but only with the next system tick interrupt, which then triggers the scheduler (Figure 3, above).
Therefore, tasks that are to be interrupted for a period shorter than a system tick can only achieve this by actively waiting via polling of the hardware timer until the desired period has elapsed. In embOS-Ultra with cycle-based resolution, however, a Delay_ms(5) results in exactly 5 ms interruption time (Figure 3, below).
And then there is the energy saving effect. Semiconductor manufacturers spend a lot of effort year after year on the development of even more energy saving microcontrollers. With embOS-Ultra you get energy savings quasi out-of-the-box.
Even if there is only one thread executing for several consecutive system ticks, the system tick interrupt will still occur periodically, thus »wasting« computing time (Figure 4, above). In addition, the status of the CPU, i.e., register contents and flags, must also be saved to the stack beforehand and then restored, which also consumes computing time.
In the same way, for example, a CPU that is in energy-saving mode when no threads are being executed must be switched back to active mode each time in order to execute the interrupt service routine. This also costs computing time and thus energy, which can be saved with embOS-Ultra. With embOS-Ultra, the CPU simply stays in energy-saving mode longer and is only woken up when there is something to do again (Figure 4, below).
Many applications today use the system tick to count the number of interrupts since system startup, either to display them in a web interface or to use them in short loops with timeouts. The simple »Tick Count«, which gives the number of timer ticks since system startup, has disappeared in embOS-Ultra. In clock cycle-based scheduling, the timer interrupt is still used, but it is not periodic. Instead, it is a single-shot timer that is programmed to generate a timer interrupt exactly when it is needed.
However, in embOS-Ultra there is a way to replace the traditional Tick Count. Namely, to replicate the tick count, one can query the cycle-based time and divide it by the clock frequency, e.g., for a 400 MHz system, calculate OS_TIME_GetCycles() / 400000. To simplify things even more, there is even an API function for this that returns this value, conveniently named OS_TIME_GetTime_ms().
Most simple RTOSes simply use a hardware timer configured to generate periodic interrupts, typically just once per millisecond. embOS-Ultra basically uses two hardware timers. One timer is used for long-term stability. This timer runs in continuous mode and does not generate interrupts. The other timer operates in single-shot mode, i.e. it counts down from a configured value to 0 or from 0 to a configured counter limit and then generates a single interrupt. If a timer is used that first counts from 0 to a configured limit, and then continues from there to the next configurable limit, even one hardware timer is sufficient for embOS-Ultra operation. However, most embedded systems have more than enough hardware timers available, so even using two timers is usually not a problem.
Unlike conventional RTOSes, embOS-Ultra calculates the number of clock cycles with 64-bit values instead of 32-bit values, which are still sufficient for counting system ticks. The resulting performance loss is minimal and not significant on modern 32-bit CPUs in practice.
The fears of 64-bit values overflowing after a certain time are also unfounded: Even on an extremely fast CPU with 1 GHz, an overflow occurs after 264 clock cycles, which corresponds to about 585 years.
In embOS-Ultra, the existing API has been left unchanged compared to embOS. Existing functions therefore behave the same in the new clock-cycle-based embOS-Ultra as they do in traditional embOS. This means that API functions such as OS_TASK_Delay() still result in the same millisecond-based timing, ensuring that the timing of an application migrating from embOS to embOS-Ultra does not change.
However, to take advantage of the new functionality, functions such as OS_TASK_Delay_ms(), OS_TASK_Delay_us(), OS_TASK_Delay_Cycles() have been added to the API to provide much more accurate timing. The same was done for the software timers provided by the RTOS.
The result is the best of both worlds: more accurate timing for modified and/or enhanced applications, while maintaining 100 % compatibility for applications that are not to be modified.
One of Segger's corporate goals is to be and remain carbon neutral. This also means making its own products – the market-leading debug probes J-Link, J-Trace and Flasher are worth mentioning here – even more energy-efficient, although they already consume less energy overall than some fans alone in competitor products. To achieve this goal, among other things, the RTOS was also targeted and with embOS-Ultra the desired result of saving even more energy were achieved.
For many years Segger has not only sold embOS to customers, but also used it as well as other components of the all-in-one embedded OS emPower OS in the J-Links and Flashers. Thus Segger is the first beneficiary of any improvement in the emPower OS and provides its customers with products that have already been proven in practice at Segger itself.
embOS-Ultra is available for many CPU and compiler combinations, including of course ARM Cortex-A/R/M and RISC-V. An embOS-Ultra port also includes a variety of board support packages for different devices and evaluation boards. This allows users to put embOS-Ultra directly into operation without any additional effort.
Last but not least, embOS-Ultra has been optimized for minimal memory consumption in RAM and ROM as well as for high speed and versatility. Throughout the development process of embOS-Ultra the limited resources of microcontrollers were always kept in mind. The internal structure has been optimized in a variety of applications with different customers to meet industry requirements. Due to the high level of modularity, only the functions that are needed are included in an application, keeping the ROM size very small. A few files are included as source code to ensure that customers do not lose flexibility and can fully customize the system to their needs.
References
[1] Schubert, H.: Concepts against supply bottlenecks – Modularity is the key. elektronik.de, 4 Oktober 2021, https://www.elektroniknet.de/international/modularity-is-the-key.190208.html.
The Author
Frank Riemenschneider
studied electrical engineering with a focus on processor architectures at Leibniz University in Hanover. He joined Segger Microcontroller in March 2021 as Marketing and PR Manager.
frank.riemenschneider@segger.com