Specification

 

 

 

Specification

 

 

Here you find a detailed description of all features offered by AVIX. By selecting a link below, you are taken directly to the subject you want to read more about.

 

 

 

 

 

- Preemptive Scheduling
- Priority Based Scheduling
- Round Robin Scheduling
- Real Time Operation
- Very Fast Task Switching
- Zero Latency Interrupt Handling
- Optimized Memory Usage

- Three Layer Interrupt Integration
- Centralized Error Handling
- Highly User Configurable
- Small Memory Footprint
- Integrated kernel object management
- Mutex support with priority inheritance
- Semaphore support

- Event group support
- Timer support
- Client Server based Message support
- Pipe support
- Memory pool support
- Highly type safe easy to use API
- Integrated Thread Activation Tracing

 

 

 

Preemptive scheduling
AVIX is a preemptive scheduler, meaning that when a thread becomes ready to run and the priority of that thread is higher than the currently active thread, the currently active thread will be interrupted instantaneously and the thread that became ready to run is activated. Top of page

Priority based scheduling
Every thread running under the control of AVIX is given a priority by the programmer. The main scheduling mechanism of AVIX is based on these priorities. AVIX guarantees the thread with the highest priority being ready to run will run. Top of page

Round Robin scheduling
Thread priorities do not need to be unique. Multiple threads can be given the same priority. Threads having the same priority are scheduled round robin, meaning those threads are given a time quantum. When a thread has been running for a time equal to this time quantum, it is preempted by AVIX and the next thread with that priority will be activated. Of course, while this round robin scheduling is going on, the threads being subject to round robin scheduling can always be preempted by a thread with a higher priority. In contradiction with many competing products, AVIX Round Robin scheduling is precise. AVIX, like other RTOSes, uses a system timer with a period in the magnitude of 100µs to 1ms. Most RTOSes use this timer period to calculate the Round Robin time slice. Due to this relative course period, competing products potentially suffer from thread starvation, meaning within a group of threads having the same priority, only one will constantly be running effectivelly blocking the others. AVIX does use a time base with a much shorter period to calculate the amount of time a thread has consumed. For this reason AVIX guarantees not to have this potential problem.Top of page

Real time operation
AVIX is a hard real time scheduler, meaning for almost all operations the time they consume is known. This makes it possible to calculate the latency of operations to guarantee they meet the system requirements. The only exceptions are operations that are typically used during system initialization when kernel objects must find each other in order to cooperate. Top of page

Very fast task switching
Task switching of AVIX is fast and deterministic. Task switching takes ~100 CPU cycles which comes down to 2.5 µs on a CPU running at 40 MIPS. This time is influenced neither by the number of threads nor the number of priority levels. To accomplish this, the internal structures of AVIX are highly optimized. The time mentioned here is the time consumed by the heart of the scheduler, that is the time it takes from the moment it is known the current active thread needs to be preempted until the new thread continues running. This time includes saving the complete context of the current active thread and restoring that of the newly activated thread. The task switch time is further positively influenced by the mechanism used to let AVIX system functions decide that a task switch is required. In contradiction with many other schedulers, AVIX does not use a structure of flags and state variables to determine the scheduler is to be activated. Checking these flags and state variables takes time and have a negative influence on the overall system performance. Instead AVIX uses a mechanism based on software interrupts to activate the scheduler core. When a system function has determined that a thread switch is needed, only one single assembler operation is required to activate the scheduler core. Top of page

Zero latency Interrupt Handling
For systems using an RTOS, good support for and integration with hardware interrupts is a must. Many RTOSes have a negative influence on the latency of interrupts. Every RTOS has an internal bookkeeping in the form of data structures and when these need to be manipulated by system functions, interrupts are disabled to prevent these data structures from getting corrupted. This has a dramatic influence on the interrupt latency . It is not uncommon an RTOS disables interrupts for tens or even hundreds of machine cycles. The worst case interrupt latency in this case is the sum of the hardware defined latency and the time the RTOS disables interrupts. AVIX is based on a revolutionary design philosophy and as a result never disables interrupts meaning it does not add a single cycle to the hardware defined interrupt latency. Still AVIX offers complete integration between the interrupt handling software and threads. Top of page

Optimized memory usage
Throughout AVIX a number of measures are taken to use the available memory as efficient as possible. AVIX offers a system stack that can be shared by all interrupt handlers. As an effect, nested interrupts do not place a large burden on the stack of each individual thread. Furthermore, the internal function structure is chosen such that in case a user thread is preempted inside an AVIX system call this happens at a point in the execution where the stack usage at the moment of preemption is minimal. Because AVIX does not allow for kernel objects to be deleted, memory allocation for these kernel objects can be done without any overhead of bookkeeping regularly required to be able to restore available memory again. Finally, functions returning information to the caller do so preferably as a result value of the function and not by passing a pointer to the function. Passing a pointer implies the referred variable must be allocated on the stack while using return values leave it up to the compiler to decide to use as many as possible of the internal registers of the controller, thereby making the stack usage smaller. Top of page

Three layer interrupt integration
The zero interrupt latency is made possible by the revolutionary architecture of AVIX. Interrupt service routines (ISR’s) dealing with hardware interrupts must be allowed to communicate with threads running under the control of AVIX. Most schedulers offer a two level approach based on ISR’s and threads. In these systems the ISR is allowed to use a subset of the schedulers functions. This leads to the aforementioned negative influence on the hardware interrupt latency. AVIX uses a different approach. In AVIX there are not only ISR’s and threads, but there is a level of software in between, called a Deferred Interrupt Handler or DIH. A DIH is a software routine running at a priority below the priority of the ISR’s but above the priority of the threads. Since a DIH runs under control of the scheduler, its interaction with the internal data structures is deterministic and does not suffer from the random behavior of ISR’s. Therefore, a DIH is allowed to make AVIX system calls without running the risk of damaging AVIX internal data structures. A DIH is enabled from an ISR. This is one of the interfaces AVIX offers from ISR’s to the other functionality. Even though a DIH is enabled by an ISR, it will be activated by AVIX. When dealing with hardware interrupts, the most time critical actions are to be taken in the ISR and less time critical work can be done in a DIH enabled from the ISR. Even less time critical actions can even be postponed to be handled from a thread activated by a DIH. This three layer architecture as opposed to the mentioned two layer architecture makes developing systems based on AVIX easier and more understandable than would be the case with the mentioned two layer architecture. Top of page

Centralized Error Handling
Again in contradiction to a lot of other RTOSes, the API of AVIX does not return any error values. When a function returns to the caller it has executed successfully. AVIX function calls do not need to be ‘enhanced’ with error checking code which obscures the real purpose of the code and easily leads to errors. The philosophy behind this is that the majority of errors that can be detected are caused by programming errors that should be solved design time before the product ships. Using AVIX, certain kinds of errors just can not occur. As described in the API section, kernel object id’s, can not be of the wrong type because they are type safe. So AVIX has no need to check the correctness of these id’s to provide the caller with an error. AVIX does check a lot of parameters supplied to a function call and its internal working. Checks that can lead to errors. When these error occur they are passed to central error handler instead of being passed back to the caller. Top of page

User Configurable Parameters
AVIX is shipped in the form of a binary library that must be linked to the user’s code. Still a number of parameters are configurable. among these are the time settings like system tick interval and round robin cycle time and the size of the data section in a message. In its current version, configuring these parameters is done by manipulating a header file (.h) supplied with AVIX. In future versions, the number of configurable parameters will be extended and a GUI based utility will be provided to ease the setting of these values. Top of page

Small memory footprint
Despite the many features and the relative high level of abstraction offered by AVIX, this is accomplished with a minimal amount of code. In its current version, the footprint of AVIX is around 10 K Bytes. Top of page

 

Integrated kernel object management
AVIX offers a number of different kernel object types as there are mutexes, timers etc. Typically these kernel objects are shared between threads. The kernel objects will however be created by one thread in order to also be used by other threads. The problem is how to share the handles to these objects between the different threads. Often global variables are used to do so, this has one very big disadvantage. A global variable holding the id of a mutex does not offer the possibility to let threads using it know that its content is valid and the mutex it identifies has already been created when another thread wants to use it. AVIX offers a solution through named kernel objects. When creating a kernel object of whatever type, it is possible to give it a human readable name. When another thread wants to access this kernel object, all it needs to do is call a Get function specifying the same name. When calling the Get function while the kernel object has already been created, its id is passed to the calling thread immediately. When the kernel object does not yet exist, the calling thread is blocked. Only when the kernel object is created by some other thread the blocked thread will be unblocked at which time it can return with the id of the newly created kernel object. At this moment the kernel object is guaranteed to exist. This mechanism greatly simplifies the synchronization typically needed during system startup and reduces the chance on errors made when using global variables referring kernel objects that are not yet created. Top of page

Mutex support with priority inheritance
AVIX offers binary mutexes. These are typically used to shield critical sections where more than one thread needs to access a shared resource. Mutexes are reentrant meaning a thread may ‘lock’ it more than once, given the number of unlock calls equals the number of lock calls before the mutex is considered to be available again. AVIX mutexes implement priority inheritance as a solution to the priority inversion problem. Top of page

Semaphore support
AVIX offers counting semaphore. Semaphores are typically used to control access to resources where more than one is available. A semaphore can be given a count. When a thread ‘locks’ the semaphore, this count is decremented by one. This continues until the count is 0. When a lock is done on a semaphore having a count of 0, the calling thread is blocked. It is only unblocked when another thread ‘frees’ the semaphore, effectivelly incrementing the count. Top of page

Event group support
AVIX offers event group kernel objects. An event group is an object containing 16 binary flags. Functions are available to set or reset one or more flags in a single call. Threads can wait on such an event group for a desired pattern of a flags to be present. When present at the moment of the call, the calling thread continues. If not, the thread is blocked until the desired pattern becomes available because of set calls executed by other threads. Event groups are global objects meaning every available function can be used by any thread. AVIX also offers thread private event groups. Every thread has an implicit event group offering the same functionality as the global event groups with one very important exception. Thread private event groups can only be waited for by the owning thread. So it is impossible for a thread to wait for the private event group of some other thread. This offers a client-server like way of working where server threads wait on their private event group for some flag pattern in order to start some activity. Top of page

Timer support
AVIX offers extensive timer support. Timers are separate kernel objects that can be created, initialized, started and stopped. Timers can be activated both as single-shot timers where, once expired, they remain in the stopped state, or as cyclic timers meaning they automatically restart once expired. Threads can wait for a timer to expire at which moment they will be unblocked and participate in the scheduling again. AVIX also offers thread private timers. Every thread has an implicit private timer that does not need to be created explicitly. Once the thread exists, the thread private timer exists. These thread private timers offer limited functionality and can only be used by the thread that owns them. For many timer applications these implicit timers offer sufficient functionality so the use of global timers can be reduced. Top of page

Client server based Message Passing
In order to exchange information between threads, AVIX offers a message passing mechanism. This mechanism is highly safe and does not allow for the programmer to make mistakes leading to overwriting memory out of the defined structures. The message passing mechanism is based on explicitly creating a message kernel object that is filled with the intended data with AVIX supplied calls. No pointer is given to the programmer that is to be used with direct pointer manipulation calls. Messages support ownership. Once a message is created, the creating thread has write ownership. Once send, the sending thread can no longer access the message. Doing so leads to an error. Once received, the receiving thread has read ownership. The receiving thread can either free the message or reuse the message. Again, when freed, the thread may no longer access it. When reused, the thread obtains write ownership. These safety features prevent errors from occurring and lead to a clean program structure. Top of page

Pipe support
Pipes are FIFO buffers usable between threads or between threads and ISR’s. The amount of data that can be contained in a pipe is user programmable and thus Pipes form an ideal communication mechanism between threads and interrupt driven devices. Top of page

Memory pool support
AVIX offers ultra high speed memory support in the form of pools containing fixed-size memory blocks. The number and size of memory blocks are user defined. Memory blocks can be allocated and freed by threads and/or ISR’s and thus form an ideal mechanism for high speed communication. Memory support timing is fully deterministic. Top of page

Highly type safe, easy to use API
The Application Programming Interface of AVIX aids in fast and error proof software development. This is obtained by making a number of interfaces to the API type safe such that errors are detected compile time instead of runtime, the latter being much harder to solve. Every kernel object is identified with an id of an AVIX supplied type. Other schedulers often use plain C pointers for this which, because they must be used for many different types, are typed as void*. This leads to type checking being completely absent and errors being hard to find. The AVIX kernel objects id’s are typed different for every different kind of kernel object. A mutex is identified with an id of type tavixMutexId, a thread with an id of type tavixThreadId and so on. Variables of these types are not interchangeable and doing so leads to a compilation error. The efficiency of this mechanism is exactly as good as it is with plain pointers and introduces zero overhead. Another example is functions receiving numeric identifiers for some parameters. Normally these are typed as an integer, meaning the programmer can pass whatever value without the compiler noting an error. AVIX has implemented strong typed enums. through sophisticated use of standard C mechanisms. As a result no wrong values can be passed. Passing a wrong value leads to compilation errors instead of harder to find runtime errors. Furthermore, AVIX does not expose any of its internal data structures, again in contradiction with many competing RTOSes. Exposing internal data structures to be manipulated directly is error prone and requires a lot of insight in the schedulers internal working. AVIX offers a purely function call based interface. The designer uses these functions without requiring any knowledge of the internals of these functions. Not only is this much easier to use but it also leads to much less errors. Again this is implemented without hurting performance by any means. Related to this last issue, nowhere does AVIX offer pointers to internal data structures to be manipulated by the system designer. This prevents a whole category of errors where memory is written by dangling pointers. Top of page

Integrated Thread Activation Tracing
One of the major benefits of AVIX is its integrated Thread Activation Tracing. Many RTOS’s offer off-line simulators showing when threads are activated in order for the designer to prove the correctness of the system. AVIX has a tracing mechanism built right into the heart of the scheduler core. To each thread one of the controllers I/O ports can be assigned. When the thread is activated this port will be set to one(1) and on deactivation set back to zero(0). Observing these signals on a logic analyzer generates a Thread Activation Diagram that can be used to prove the correctness of the system. The strength of this mechanism is that it is always present. When a system is based on AVIX this tracing is right there, both in the development environment and, if desired, in the shipped product. The mechanism’s implementation is highly efficient and only consumes 10 machine cycles, meaning 250 ns (nano seconds!) on a CPU running at 40 MIPS. When using the Logic Analyzer’s trigger facilities to observe this tracing, the mechanism can be used to find errors in the timing of the system. Thread Activation Tracing offers tremendous possibilities for obtaining insight in the scheduling of the system. Using this mechanism, it is easy to observe the scheduling and timing of the system and see what the effect is when certain parameters like thread priorities are changed.Top of page

 

 

 

AVIX-RT © 2007, All Rights Reserved

Legal Disclaimer

Privacy Policy