VELOOS – Very Low Overhead Operating System
VELOOS is a message-triggered cooperative operating system designed to run in places were a large vehicles can not run. Its implementation for PIC12F takes less than 200 instructions and 20 data registers1. With addition of a timer driver, it becomes a time-triggered RTOS.
Preface
What is a real-time operating system in context of an MCU? First, it is an abstraction intended to share MCU resources among application components. Whatever abstraction is used in RTOS, it drives the application design – e.g. if a RTOS operates in terms of tasks, an application developer is obeyed to program application as a set of tasks.
Secondly – it is a set of services which an application developer may/should use to make application operable and achieve the application goals. Most common abstraction for RTOS is a multitasking. Multitasking has several advantages, which make it very appealing, however it also has disadvantages which are even more noticeable in context of an MCU applications.
Disadvantages of multitasking
1. It is costly (high resource consuming)
Task switching requires saving and restoring task context, which includes stack, some system registers and some hardware SFR’s (such as status).
2. Inter-task communications even more costly
Tasks abstractions were designed for executing rather isolated and limited in time routines. Task communication and synchronization requires use of other abstractions, such as semaphores, pipes, etc. These
communications/synchronizations features are usually accessible as functions and they are not trivial in implementation and use.
3. It is not well suitable for event driven applications
Many of MCU applications are event-driven – a particular application routine is executed on e response of an external event. When implementing such application with a multitasking, developer should map application requirements to available abstractions – e.g. decompose the application onto tasks. For an event-driven application this mapping is not trivial and creates unnecessary complications.
4. It is redundant
Multitasking assumes decomposing application on isolated or loosely coupled set of tasks which, due to nature of MCU applications, are implemented as infinite loops – every task implements an infinite loop. Memory allocated to a task usually is not used in other tasks, even if the task is in idle mode.
Alternate RTOS abstraction
Messaging is an alternate abstraction, which fits better for event-driven applications. With this abstraction an application is decomposed to set of process data objects (PDO) which receive and send messages in a response to other messages or external events, such as port change, periphery interrupts or timer.
Messaging provides a simple mechanism for both sharing CPU time and communicating among PDO’s. Despite messaging is also not a perfect abstraction, it requires fewer resources and needs implementation of very few and very simple abstractions – message, message queue, send message, and message handlers. All other abstractions and mechanism can be built with (on top of) these four and this is how VELOOS is designed and implemented.
VELOOS description
VELOOS design is based on few rather simple design decisions for establishing message processing.
Terminology
(It also reflects major design decisions)
Message | A fixed-size set of sequential general-purpose registers. Message embeds accepter address, message ID and applications data. By default, message is 4 bytes long with 2 bytes available for custom data. |
Message Queue | A circular buffer of fixed configurable size. |
Send Message, Post Message |
A routine that accepts object handle and message ID, places them into the message area and returns indirect access register pointing to custom data locations. Messages are sent in asynchronous mode – sender does not wait until accepter processes the message. |
Message Handler | A routine provided by application developer for processing messages. This routine is invoked by the system when it encounters a message addressed to the object. |
Addressing Modes | Messages can be addressed to a specific object (direct addressing) or to all registered objects (broadcast addressing). The latter one is indicated by use of a reserved object address – FF |
Broadcast Message | Message sent to all instantiated objects |
Object Address, Handle |
An 8-bit value uniquely identifying an object. In VELOOS, handle is a synonym of Object Address. VELOOS makes up handle values from lower octet of object entry address. |
Object Entry | Pair {class pointer, object data} placed in the object registration section. |
Object Instantiation | Predefined and required way of registering objects in the OS. It creates registration entry in the system and provides value for the object handle. Currently VELOOS implements only build-time object instantiation. |
Object Initializer | An application routine provided by the application developer for initialization of registers and periphery used by a particular PDO instance. It is called on system startup. |
Object Data | Any 8-bit value provided by the application developer and suitable for distinguishing among object instances. The system makes no assumption on object data value, it just loads it to system variable This. |
Class | Set of entries/routines required for instantiating and operating an object – e.g. handler and initializer. |
Class Entry | Pair of jumpers {goto handler, goto initializer} used for dispatching the system calls to an object |
Class Pointer | Lower octet of class entry address |
Class Definition | Predefined and required way of registering classes in the OS. It creates class entry in the system and provides value for the class pointer |
VELOOS driver | Software that provides access to a shared resource and/or handles interrupts. A driver may consist of an object and an interrupt handler (IH)- a fragment of interrupt service routine. |
Boot Handler | Fragment of application startup routine, provided by a PDO or driver for initializing of resources not associated with a particular PDO. |
Interrupt Handler | Fragment of ISR provided by the application or a driver for handling concrete interrupt. Custom ISR are ordered and linked accordingly to (logical) priority assigned to it. VELOOS provides the prolog and epilog handlers, which provide context saving and restoring. |
Principle of Operations
System Startup | On reset, system executes internal startup routines, and application boot handler. Then system enumerates trough object registry and for each entry calls object initializer. |
Interrupt Handling | On an interrupt, the prolog handler saves all critical SFRs in temporary registers. Then control is transferred to a next interrupt handler. IH check the interrupt source and if the source is proper, handles the interrupt. As a result of handling an interrupt, IH may post a message. If the source improper, IH skips its body. After all IH were executed, control is transferred to the epilog handler, which restores the context and exits the interrupt. |
Operating Mode | VELOOS points to the next message in the queue, retrieves accepter address from the message. If it is a broadcast message, system enters broadcast state. Otherwise, it enters Call Handler State. |
Call Handler State | System loads the accepter’s class pointer to system variable This_class and object data to system variable This and calls the message handler. The message handler is expected to complete execution in a predefined timeframe. If it does not, system enters into timeout state. During processing a message, PDO may post message(s) to other objects, including message(s) to itself and broadcast messages. When the message queue is empty, system enters Idle state. |
Broadcast State | VELOOS enumerates trough object registry and for each entry it calls corresponding handler. |
Idle State (optional) | VELOOS maintains posts Idle message and calls handler for the next object. If the message queue is not empty after this call, system leaves idle state. VELOOS maintains a dedicated ‘next idle object’ pointer, which is incremented after each handler is call for the idle message. This ensures that every PDO gets idle message. |
Timeout State | If a PDO fails to handle message in the given timeframe, VELOOS will abort handler routine and proceed with the next message in the queue. VELOOS provides two optional mechanisms for controlling execution time – the hardware watchdog timer (WDT) and software WDT based on a timer driver. Both mechanisms may work simultaneously. |
Message Queue Overflow | When the message queue is overflowed, system sets Queue Overflow flag and overwrites an existing message – the first in the queue. |
Time Triggering | Time triggering is implemented with a heartbeat broadcast message sent by a timer driver with fixed periodicity (1 ms by default). VELOOS timer drivers also have option for additional 1 sec heartbeat. |
Time Intervals | VELOOS does not provide an explicit mechanism for controlling time intervals between object activations. PDOs are expected to watch for proper time interval via heartbeat, using either time value provided with the heartbeat message or using countdown approach. |
VELOOS drivers | Currently VELOOS provides two drivers: TMR0 based timer driver and TMR2/CCP based timer driver. |
Persistent Storage | VELOOS provides two options for storing object registry – ROM and EEPROM. Class registry is stored in ROM. |
Call Back | Callback is a message sent back from the accepter to the sender. System places sender’s handle as the last byte in the message and if the PDO does not override it, the accepter may use this handle to send a message back. |
VELOOS implementation
VELOOS is designed and implemented in MP ASM language. Its primitives are implemented as ASM routines or macro.
VELOOS requirements
PIC family Feature |
PIC12F675 program/data |
PIC16F690 program/data |
PIC18F |
Bare operating system | 195/20 | 220/20 | 210/20 |
Heartbeat Timer (1ms, 1s) | 75/7 | 85/7 | 70/7 |
A definition of class (per class) | 2/0 | 2/0 | 2/0 |
An object instance (per object) | 2/0 | 2/0 | 2/0 |
Possible extensions
Simple Networking with VELOOS
Messaging approach used by VELOOS allows implementing simple distributed computing in a simple and transparent way. First of all networking would need a network driver (a VELOOS class) that implements physical communication between MCU’s. This driver should be able to (1) filer incoming messages, (2) pack and send filtered messages via communication channel, (3) unpack messages coming from the communication channel and (4) post them to local message queue. Then, for every remote object application should instantiate a local proxy object (as an instance of network driver class). With this approach, an application can be easily distributed among several execution nodes (MCUs).
Various object lifetime
Currently the system implements only one lifetime scope for PDO. It is possible to extend this implementation for static objects (stored in ROM), persistent objects (stored in EEPROM), and dynamic objects (created in run-time and stored in RAM).
Exception handling
Currently the system has two exceptional situations (Handler Timed Out and Message Queue Overflowed) and provides no ability for changing behavior on these exceptions. VELOOS can be extended with exception handler support, by, for example, providing third jumper to the class entries, which would be called by the system when an exception occurs.
Class and Object Directory
Currently the system does not provide a mechanism for retrieving a list of classes and objects registered in the system. This feature can be implemented by class entry with additional jumper, which would return
class/object identification data in for, for example, human-readable class/object names.
Related Posts
VELOOS Example1 – Self-triggering PDO
VELOOS Example2 – Heartbeat Driven PDO
VELOOS Example3 – USART Controlled actuators and Generators
MIHA675 – a sample VELOOS application
Future Posts
VELOOS sample application (planned)
VELOOS reference (planned)
2 Comments