[previous]
[index]
[next]
Example 1: Pure Periodic Scheduling of a Single Task
This example demonstrates a single fixed-period task that toggles
the speaker at 1 kHz, also demonstrating how to read and write I/O
addresses. In this example we will introduce the basics of RT Linux,
and refer to the commented
source code of the example for the details.
Principle of Operation
- In RT Linux, the real-time scheduler is driven by timer
interrupts from the PC's 8254 Programmable Interval Timer (PIT) chip.
- In pure periodic mode, the timer is programmed to expire at
a fixed period. All tasks will run at a multiple of this period.
- The advantage is that timer reprogramming is avoided, which saves
about 2 microseconds.
- The disadvantage is that tasks are forced to run at multiples of
the fundamental period.
- In one-shot mode, the timer is reprogrammed at the end of
each task cycle, so that it expires exactly when the next task is
scheduled to run.
- The advantage is that tasks timing can vary dynamically, and new
tasks can be added without regard to any fundamental period.
- The disadvantage is that timer reprogramming overhead recurs
continually.
- In this example, we will show how a single task is set up to run
in pure periodic mode.
Setting Up a Single Periodic Task
The relevant RTAI functions are documented in the RTAI
documentation. In this example we will do the following:
- Set up the timer with a fundamental period, in our case 1
millisecond.
- Define the task function, in our case
toggling the speaker port.
- Set up the task structure and fill in fields for the task code,
its priority, size of stack and other information.
- Schedule the task to run at a specified period, a multiple of the
timer period.
Setting Up the Timer
The Task Function
Setting Up the Task Structure
- An RT_TASK data structure is used to hold all the information about a
task:
- the task function,
- any initial argument passed to it,
- the size of the stack allocated for its variables,
- its priority,
- whether or not it uses floating-point math,
- and a "signal handler" that will be called when the task becomes active.
- The task structure is initialized by calling
rt_task_init(RT_TASK *task,
void *rt_thread, int data,
int stack_size, int priority,
int uses_fp, void *sig_handler);
- 'task' is a pointer to an RT_TASK type structure whose space must
be provided by the application. It must be kept during the whole
lifetime of the real time task and cannot be an automatic
variable.
- 'rt_thread' is the entry point of the task
function.
- 'data' is a single integer value passed to the new task.
- 'stack_size' is the size of the stack to be used by
the new task (see Example 9 for information on computing stack size).
- 'priority' is the priority to be given the task. The highest
priority is 0, while the lowest is RT_LOWEST_PRIORITY (1,073,741,823).
- 'uses_fp' is a flag. Nonzero value indicates
that the task will use floating point, and the scheduler should make
the extra effort to save and restore the floating point registers.
- 'sig_handler' is a
function that is called, within the task environment and with
interrupts disabled, when the task becomes the current running
task after a context switch.
- The newly created real time task is initially in a suspended
state. It is can be made active either with
'rt_task_make_periodic()', 'rt_task_make_periodic_relative_ns()' or
'rt_task_resume()'.
Scheduling the Task
Running the Demo
To run the demo, change to the 'ex01_periodic' subdirectory of the
top-level tutorial directory, and run the 'run' script by typing
./run
Alternatively, change to the top-level tutorial directory and run the
'runall' script there by typing
./runall
and selecting the "Single Periodic Task" button.
You'll hear a tone corresponding to 1 KHz toggling (500 Hz for a
full period) for about 10 seconds.
See the Code
Next: Example 2: Pure Periodic Scheduling of Two Tasks
Back: The Basics of Real-Time Linux