ALERT: "A Light Embedded Real-Time" operating system for micro-controllers
ALERT features...
The kernel module (rtos.c) contains support code and device interface functions for:
The kernel is easily scalable to include required features and to exclude unwanted features.
ALERT provides additional code to support these options...
The application firmware only needs to include required RTOS support modules.
ALERT will allow you to implement small embedded applications with many of the benefits of a more sophisticated RTOS, e.g. robustness and reliability of execution, ease of code maintenance and extension, but with minimal overheads on processor and memory.
Characteristics of ALERT
ALERT supports simple "Foreground/Background" processing, where background tasks may be interrupted by foreground tasks. (A "foreground" task is any interrupting task.) The kernel provides a task scheduler for periodic background tasks. Simplicity is achieved by compromise... of course.
The overall philosophy is to put as much as possible of the application code into background processes, i.e. scheduled tasks and the (optional) Command Line Interface (CLI). Background tasks are best implemented using a "state machine" model of some sort, because they are not permitted to cause delays. In this minimal RTOS design, background tasks have only two possible "status" values: ACTIVE and SUSPENDED. Active tasks are executed in a round-robin sequence. When a task is complete, it sets its own status to Suspended.
Background tasks are not time-critical, but must have short execution times on each call, so that the sum of all B/G tasks execution times is normally less than the minimum B/G task period. Occasional overruns can be tolerated, as long as not excessive in duration or frequency. (The definitions of "occasional" and "excessive" depend on the application and the watchdog time-out interval!) Background task overruns are monitored by the kernel, for diagnostic purposes.
Background tasks may be scheduled periodically by the Task Scheduler, or they may be invoked on an 'ad hoc' basis, as required, e.g. by a CLI command function or by another task.
Tasks are not permitted to contain "wait loops". If a process involves waiting for some external event to happen, e.g. a delay timer to expire, or another task to complete, or whatever, the process should be implemented as a "state machine". While a task is "stuck" in the same state, waiting for an event to occur before it can advance to a subsequent state, it should return immediately but remain in the ACTIVE state. This has the effect of allowing all other Active tasks to execute without disruption.
In any RTOS, care must be taken to prevent data corruption during data transfers between tasks. More sophisticated RTOS's use semaphores, message queues, etc, to control inter-task data communications. ALERT uses a simpler, more efficient approach...
There is no difficulty with data transfers between background tasks, since they are inherently prevented from "interrupting" each other at inconvenient times. As the majority of processing occurs in background, inter-task communications will rarely require special handling. Similarly, assuming the application disallows nesting of interrupts (with possible exemptions), there is no need to control data transfers among foreground tasks. In a nutshell, while a task (foreground or background) is processing data that another task needs to read, the data is never available for reading until the update is complete. Shared data simply cannot be modified by one task while it is being read by another.
ALERT does not provide generic mechanisms for synchronisation of inter-task data communications. There are two reasons for this: 1) Such mechanisms can add significant overheads to processor load and memory requirements; 2) Mechanisms developed specifically to suit the application are likely to be more efficient and less obscure than a generalised set of system calls.
Data transfers between background and foreground need to be carefully controlled to prevent errors due to one ground reading data while the same data is being modified by another. Background tasks must disable interrupts during multi-word data transfers and then restore the interrupt status afterwards. Double-buffering is a reliable technique for managing data transfers. (For example, see ReadRTCdateTime(). )
Nesting of foreground tasks which share multi-word data structures with other F/G tasks is prohibited, i.e. such tasks must be prevented from interrupting each other. F/G tasks that do not share multi-word data structures with other F/G tasks may interrupt freely.
Applying these guidelines to firmware based on ALERT will help you to implement reliable error-free applications.
How to incorporate ALERT into a firmware application
The best approach is to design the application around ALERT from the beginning. Incorporate the application into ALERT, not the other way around. Attempting to adapt an existing application to ALERT or any other 3rd-party RTOS, with minimal restructuring, is going to give you headaches.
Step 1:
Understand how ALERT works and how best to build your
application code around it. ALERT has been designed to be largely
"self-documenting", i.e. the source code and
comprehensive annotation therein should give the developer
sufficient understanding of its workings. The sample program (AT89c5131
debug monitor) shows how application-specific code is best
incorporated, i.e. as a number of background tasks which
interface with ALERT by means of "system calls"...
(System calls are functions which the RTOS provides to facilitate
interfacing of the application code with system resources such as
the real-time clock, timers, serial data communications devices,
digital inputs and outputs, analog inputs, control surface
switches and indicators, displays, non-volatile memory, etc.)
Step 2: Decide which of ALERT's kernel features are required. Customise the kernel module (rtos.c) accordingly.
Step 3: Decide which of the additional modules are required, i.e. CLI facility (including Debug Monitor).
Step 4. Flesh out the kernel with I/O device drivers to suit your particular MCU type and peripheral hardware (in module rtos.c). Use the sample I/O drivers (as provided for the AT89c5131 evaluation board) as a guide, substituting code to suit your target hardware platform. (Other sample processors will be added soon, hopefully. Donations of code would be gratefully received.)
Step 5: Extend the kernel module, if necessary, to provide support for additional resources, e.g. LCD panel, analog I/O, etc.
Step 6: Design and code application-specific tasks, making the most out of available system calls in the ALERT kernel and CLI modules. Stick to the guidelines in the Overview section above.
Command Line Interface (CLI)
A command string is composed of a 2-letter command "name" and a number of user-supplied "arguments" (parameters). Some commands have no arguments. A single space must be inserted between command line arguments, where there is more than one (including the 2-letter command name). CLI input is generally not case-sensitive.
A list of available commands is output by entering the "help" command, "HE". Square brackets enclosing a command argument mean that the argument is optional. (Don't type the brackets!) Refer to "help" messages for command syntax details.
USB Comm's Option (AT89c5131 "Eval" firmware)
The CLI is accessible from either the USB port or the "RS-232" async serial port (UART). The sample Eval 'C5131 program starts up in UART mode by default. The host PC terminal emulator software must be configured to use 38400 Baud, 1 stop bit, 8 data bits, and no parity bit. Of course, these defaults can be altered in the source code and the firmware recompiled.
To switch the "host serial I/O stream" from UART to USB or vice-versa during program execution, the host simply sends 3 ASCII 'SYN' chars (Ctrl+V) in succession. This will set the I/O stream to the source of the 'SYN' (Ctrl+V) codes.
If using the USB port, the host PC needs a suitable USB device driver. A standard USB "Communications Device Class" (CDC) driver should allow a "virtual" COM port to be configured for use with any PC application (e.g. HyperTerminal). MS Windows 98SE/98ME, 2000 and XP all have a built-in USB 'CDC' driver. A driver information file (c5131_cdc.inf) is provided by Atmel for device installation. Windows' USB device installation wizard may (or may not) ask for the device information file when the 'C5131 Eval Board is first plugged in.
HyperTerminal can be used to access the CLI via the USB port at a signalling rate of 12Mbps! HyperTerminal will need to be configured to use a "virtual" COM port, which should manifest itself automatically when a USB connection has been established between the host PC and the 'C5131 Eval Board. For example, if the host PC has four physical serial ports, COM1 thru COM4, then 'COM5' should magically appear in HyperTerminal's 'Serial Port Setup' dialogue box as a selectable option. This will only happen if Windows 'CDC' driver has recognised the 'C5131 Eval Board and "attached" it. Otherwise, HyperTerminal setup is the same as for a physical COM port ("direct connect" to COMx). There is no need to select a Baud rate.
HyperTerminal running under Windows XP seems to be a bit quirky. It may be necessary to fiddle around with the USB connection (disconnect and reconnect the USB cable), and/or reset the board, and/or restart HyperTerminal, and/or disconnect/reconnect to the port (HyperTerminal tool buttons), not necessarily in that order, to establish communications! Remember to hit Ctrl+V three times after every change until you get the CLI prompt.
Copyright 2004++ Michael J Bauer
Contact: mjbauer@hotkey.net.au
Website: http://www.hotkey.net.au/~mjbauer/free_ip.htm