Introducing the µT-Kernel
Written by: Mohit Sindhwani (Viometrix Private Limited)
In an earlier article, I had discussed the future directions with the T-Kernel and had pointed out that the μT-Kernel was likely to be an important piece of the puzzle when it comes to small devices. Even at the TRON Show 2007 (December 2006), there was plenty of talk about the μT-Kernel – an implementation of the T-Kernel for small-scale embedded systems. Subsequently, in March 2007, the T-Engine Forum released the specifications and reference source code for the μT-Kernel. In this article, perhaps the first article in English about the μT-Kernel, I will introduce the μT-Kernel and highlight some of its design decisions and features while also discussing its availability and the main points of difference from the T-Kernel.
Round 1: T-Kernel
No introduction to the μT-Kernel will be complete without first looking at the T-Kernel since the μT-Kernel was crafted to address a segment of embedded systems in which the T-Kernel is a bit of an odd fit. One of the main aims with the T-Kernel (and the T-Engine) was to provide an open specified platform for the rapid development of embedded systems. Towards these aims, decisions were specifically taken to ensure that the T-Kernel would serve as software infrastructure that would allow a high level of software portability for device drivers, middleware and other software subsystems.
In terms of its technical target, the T-Kernel was targeted at larger embedded systems with the placid assumption being that the main processor in the system is a 32-bit CPU with or without a memory management unit. Also, sufficient memory was assumed to be present in the system. Consequently, the T-Kernel specification deals primarily with 32-bit integers and specifies support for complex requirements such as virtual memory, task exceptions and extensive support for the creation of subsystems.
At the same time, the T-Engine Forum provides the single source for the implementation of the T-Kernel so that there is no fragmentation of the kernel – this is deemed especially important to ensure that independent software vendors can create portable middleware for the T-Engine/ T-Kernel platform. Therefore, by 2005, the source code for the T-Kernel and a number of ports was made public and was available to anyone who registered for free to download the code. The download included the specification and implementation of a production-ready hard real-time OS in source code form. Of course, some work was needed to get this running on your target since the T-Monitor was not supplied with the source code for reasons such as its hardware-specific nature. System developers were, of course, free to adapt and modify the kernel to suit their designs better but they were not allowed to redistribute the source for the modified kernel.
While the assumptions towards 32-bit processors do hold true for a large number of embedded systems being designed today, embedded systems designers know that a 32-bit processor with/ without an MMU is not the answer for all types of designs. There is still a very large market for 8- and 16-bit controllers that either do simple jobs, or support the larger central processors in the system. I am told by other industry people that this especially true for Asia (outside Japan) where the cost conscious are always trying to derive as much juice as possible from the tiniest controllers. Therefore, the question was: can an RTOS run on these controllers, and more importantly, was the T-Kernel in its specified form the most suitable architecture for these controllers?
A number of attempts were made to port the T-Kernel to smaller controllers while still staying within the limits of the license of the T-Kernel. It was found that some portions of the specification were not relevant/ applicable to smaller controllers (due to hardware limitations) and inefficient or non-compliant implementations would result in attempting to fit the T-Kernel into such environments.
These observations about the T-Kernel formed the background for the creation of the specifications and reference source of the μT-Kernel.
Enter the μT-Kernel
If you read the specification for the μT-Kernel, the intent is quite clear – the μT-Kernel has been designed to prioritize optimization, efficiency and performance over portability. As a result, a number of functions that are considered as being an unnecessary overhead in small systems have been removed. Also, the licensing and availability has been modified slightly to make it easier to change the μT-Kernel such that it better suits the specific target.
However, there is also an attempt made to maintain a high level of compatibility between the μT-Kernel and the T-Kernel so that the bulk of the investment made into the creation of device drivers and middleware is not wasted. For example, a number of device management functions have been retained so that it is easier to port and use device drivers that were created for the T-Kernel. Therefore, it is quite possible to port applications, device drivers and middleware from the T-Kernel to the μT-Kernel if certain porting guidelines are followed.
All the main technical differences between the T-Kernel and the μT-Kernel arise from two main points of difference:
- The μT-Kernel typically assumes a smaller embedded system with constrained resources and a 16-bit CPU rather than 32-bit CPU as the main processor in the system. Note that this does not mean that it runs only on 32-bit processors – it just means that it is designed so that it runs well on 16-bit CPUs and perhaps even better on a 32-bit CPU.
- The μT-Kernel assumes that the system does not have any support for virtual memory and is therefore unable to provide for different levels of task level protection.
Technical Differences from the T-Kernel
Much of the remaining part of this section has been extracted from and is based on the μT-Kernel specification.
Due to the assumption that the target system will not have support for virtual memory, the μT-Kernel has a single address space that comprises of entirely resident memory and does not include any concept of protection levels (in real fact, tasks can be created at different protection levels but all operations are treated as being executed at Protection Level 0).
Due to the assumption that the base CPU might be 16-bit, there are some limitations on the maximum values that some variables can take. For example, the maximum count that can be assigned to a semaphore has been changed to 32767 instead of 65535. Such limitations may exist for parameters that rely on the INT data type (which is 16-bit in most 16-bit processors). Another example of modules that will be affected by this limitation are message passing modules that may be allowed to specify a maximum transfer size of 32767 bytes per message.
In the μT-Kernel specification, a number of items have been not been explicitly specified and are left as being “implementation defined”. This is due to the fact that efficiency and performance have a higher priority than portability in the design of the μT-Kernel. Examples of implementation-defined features include specifications relating to system calls, exact values of function codes, and the distinction between system-specific and implementation-dependent portions of object attributes. This is unlikely to have much impact when developing programs for a single implementation of the μT-Kernel, but developers should take careful note of these items since they might affect the portability of the software that is developed.
In the μT-Kernel, implementation of system calls is defined to be implementation-defined as against being a library that is compiled with the application. Although having a system call library allows a higher level of portability between different compilers, this has been done to ensure that system designers can select the most efficient method of providing the RTOS functionality to the developers. Most importantly, this allows for implementations in which the μT-Kernel can be compiled along with the application rather than being a separate entity that launches the application.
Due to hardware limitations and in the interest of performance, the μT-Kernel does not include support for the following features:
- Task exceptions
- System memory management
- Address space management
- I/O port access support
- Power saving
- System configuration information management
Also, some functionality has been removed from the following modules:
- Task management
- Task-dependent synchronization
- System state management function
- Subsystem management function
- Interrupt management function
The μT-Kernel itself adds functions that allow the user to specify which memory is used for the task stack and message buffer memory pool. This allows designers to place these structures in higher speed memory so that higher performance is achieved.
Optional Debug Support
While the T-Kernel requires that debug support be implemented, it is up to the developer to decide whether or not to implement debug support for the μT-Kernel. This is due to the fact that debug support in some small systems may be considered an unnecessary overhead.
A couple of other implementation differences have been highlighted by another engineer to me: the μT-Kernel does not require the use of the T-Monitor since the boot up code and basic T-Monitor commands are integrated into the μT-Kernel source code. Also, each kernel module can be selected via a configuration file so that minimum memory usage can be achieved.
Primarily, the μT-Kernel is available as an open specification and open source reference source code. The specification naturally details every system call with information about the parameters it expects, the error codes it returns, a detailed description of its functionality and notes about specific usage. At the same time, the specification includes clear information about what functions are missing from the μT-Kernel and what impact it has on the portability of software. Where relevant, porting guidelines are also provided on a per-system call basis so that programmers know what changes will be needed if the software is ported to the T-Kernel (or vice versa).
The reference source code is provided as “one implementation” of the μT-Kernel and developers are free to decide how they want to use it. For example, developers may choose to use it as it is for their systems, adapt it to be more efficient or even rewrite a μT-Kernel compatible RTOS from scratch.
The reference source and the specifications can be downloaded from the website of the T-Engine Forum.