|
|
A Linux-based Real-Time Operating System
#3
Apendix
A: Real-Time Task Interface
Task
Control
Real-Time
FIFOs
Interrupts
Apendix
B: The PC Speaker Driver Code
References
- 1
- Michael Beck, Harald Böhme, et al. LINUX Kernel
Internals. Addison-Wesley, 1996.
- 2
- Alan Burns. Scheduling hard real-time systems: A review.
Software Engineering Journal, 6(3):116-128, 1991.
- 3
- Bill Crum. Data acquisition and control using Real-Time Linux.
Master's thesis, New Mexico Institute of Mining and Technology, 1997.
- 4
- Borko Furht, Dan Grostick, et al. Real-time UNIX systems:
design and application guide. Kluwer Academic Publishers Group,
Norwell, MA, USA, 1991.
- 5
- Bill O. Gallmeister. POSIX.4 - Programming for the Real
World. O'Reilly & Associates, 1995.
- 6
- P. M. Herlihy. Wait-free synchronization. ACM Transactions
on Programming Languages and Systems, 13(1), January 1991.
- 7
- Dan Hildebrand. Implementing the Win32 API over a POSIX realtime OS.
Available from http://www.qnx.com/whitepaper/qnxwin32.html.
- 8
- Dan Hildebrand. An architectural overview of QNX. In USENIX
Workshop on Micro-Kernels and Other Kernel Architectures, pages
113-126, Seattle, WA, April 1992. USENIX.
- 9
- Dan Hildebrand. A microkernel POSIX OS for realtime embedded
systems. Technical report, QNX Software Systems Ltd, 1993.
- 10
- IEEE. Information Technology -- Portable Operating System
Interface (POSIX) -- Part 1: System Application: Program Interface.
IEEE/ANSI Std 1003.1, 1996 Edition. Order Number SH94352-NYF.
- 11
- IEEE. Information Technology -- Portable Operating System
Interface (POSIX) -- Part 2: Shell and Utilities. IEEE/ANSI Std
1003.2-1992 & IEEE/ANSI 1003.2a-1992. Order Number SH17129-NYF.
- 12
- Intel Corporation. Pentium Processor Family Developer's
Manual. Order Number 241430-004.
- 13
- Intel Corporation. Intel486 (TM) Processor Family. Programmer's
Reference Manual, 1995. Order Number 240486-003.
- 14
- Markus Kuhn. A vision for Linux 2.2 -- POSIX.1b compatibility and
real-time support. Available from .
- 15
- Samuel J. Leffler, Marshall Kirk McKusick, Michael J.
Karels, and John S. Quarterman. The Design and Implementation
of the 4.3BSD UNIX Operating System. Addison-Wesley, Reading, MA,
USA, 1989.
- 16
- Jochen Liedtke. On micro-kernel construction. In The Proceedings
of the 15th ACM Symposium on Operating Systems Principles, December
1995.
- 17
- C.L. Liu and J.W. Layland. Scheduling algorithms for
multiprogramming in a hard-real-time environment. Journal of the
ACM, 20(1):44-61, January 1973.
- 18
- Henry Massalin. Synthesis: An Efficient Implementation of
Fundamental Operating System Services. PhD thesis, Columbia
University, 1992.
- 19
- Milan Milenkovic. Operating Systems: Concept and Design.
McGraw-Hill, 1992.
- 20
- Dennis W. Ritchie and Ken Thompson. The UNIX time-sharing
system. Communications of the Association for Computing
Machinery, 17(7):365-375, July 1974.
- 21
- Lui Sha, Ragunathan Rajkumar, and John P. Lehoczky. Priority
inheritance protocols: An approach to real-time synchronization.
IEEE Transactions on Computers, 39(9):1175-1185, September
1990.
- 22
- Sang H. Son, editor. Advances In Real-Time Systems,
chapter 10, pages 225-248. Prentice Hall, 1984.
- 23
- Daniel Stodolsky, J. Bradley Chen, and Brian Bershad. Fast
interrupt priority management in operating system kernels. In The
Proceedings of the 2nd USENIX Symposium on Microkernels and Other Kernel
Architectures. USENIX, September 1993.
- 24
- Andrew S. Tanenbaum. Modern Operating Systems.
Prentice Hall, 1992.
- 25
- Martin Timmerman and Jean-Christophe Monfret. Windows NT as
real-time OS? Real-Time Magazine, 1997. Available from
http://www.realtime-info.be/encyc/magazine/articles/winnt/winnt.htm.
- 26
- Gabriel A. Wainer. Implementing real-time services in MINIX.
Operating Systems Review, 29(3):75-84, July 1995.
- 27
- Wind River Systems, Inc., 1010 Atlantic Avenue, Alameda, CA
94501-1147, USA. VxWorks Programmer's Guide 5.1, December 1993.
Apendix A: Real-Time Task
Interface
The material of this appendix is valid for
Real-Time Linux version 0.5.
Task
Control Real-Time
FIFOs Interrupts
Task Control
typedef
struct rt_task_struct RT_TASK;
Each real-time task is represented
by a rt_task_struct structure. It contains task state, priority, and other
parameters. The structure is opaque.
int rt_task_init(RT_TASK
*task, void (*fn)(int data), int data, int stack_size, int priority);
Initializes the task structure pointed to by task. fn is the code
for the new task; data is the value to pass to fn on
startup; stack_size is the stack size to be allocated for this task.
priority is task priority. It ranges from 1 (the highest)
to RT_LOWEST_PRIORITY.
int rt_task_make_periodic(RT_TASK *task,
RTIME start_time, RTIME period);
Marks this task as periodic; if
the task is to start execution immediately, the return value of
rt_get_time() can be used as start_time.
int
rt_task_delete(RT_TASK *task); Deactivates the task.
int
rt_task_wait(void);
Suspends execution of the calling task until
the beginning of the next period (for periodic tasks only).
int
rt_task_suspend(RT_TASK *task); Suspends the task.
int
rt_task_wakeup(RT_TASK *task); Resumes execution of the task.
void rt_use_fp(int flag);
Signals to the scheduler if
floating point context needs to be preserved for this task. A non-zero
value of flag makes the FP context to be saved on each context switch.
The flag value of zero makes the opposite.
typedef long long
RTIME; Time is measured in clock ticks that are system-dependent.
long long RT_TICKS_PER_SEC; This constant is equal to the
amount of clock ticks in one second.
RTIME rt_get_time(void);
Returns the amount of time passed from the boot-up until the
present moment. This time does not necessarily correlate with Linux
time.
Real-Time
FIFOs
int rtf_create(unsigned int fifo, int size);
Creates the FIFO buffer number fifo. size is the initial size of the
buffer.
int rtf_destroy(unsigned int fifo); Deactivates the
FIFO. The buffer memory is freed.
int rtf_resize(unsigned int
fifo, int new_size); Resizes the FIFO.
int
rt_fifo_put(unsigned int fifo, char *buf, int count);
Attempts to
write count bytes to the FIFO identified by fifo from the buffer starting
at buf. Returns -1 if there is not enough space in the FIFO; otherwise
returns count.
int rt_fifo_get(unsigned int fifo, char *buf, int
count);
Attempts to read count bytes from from the FIFO identified
by fifo to the buffer starting at buf. Returns -1 if there is not
enough data in the FIFO; otherwise returns count.
int
rtf_create_handler(unsigned int fifo, int (*handler)(unsigned int fifo));
Attaches a handler to the FIFO.
The function handler will be
called whenever a Linux process reads or writes to the FIFO. When the
handler is called it is passed the FIFO number as the argument.
Interrupts
int
request_RTirq(unsigned int irq, void (*handler)(void)); Installs the
interrupt handler for interrupt number irq.
void
free_RTirq(unsigned int irq); Uninstalls the interrupt handler for
interrupt irq.
Apendix B:
The PC Speaker Driver Code
#define
MODULE #include <linux/module.h>
#include
<linux/rtf.h> #include <asm/rt_irq.h> #include
<linux/mc146818rtc.h>
#define CMOS_IRQ 8
static
int filter(int x) { static int oldx; int ret;
if (x &
0x80) { x = 382 - x; } ret = x > oldx; oldx = x; return
ret;
}
void intr_handler(void) { char data; char
temp; (void) CMOS_READ(RTC_REG_C); /* clear IRQ */ if (rtf_get(0,
&data, 1) > 0) { data = filter(data); temp = inb(0x61);
temp &= 0xfd; temp |= (data & 1) <<
1; outb(temp,0x61); /* out to the speaker */ } }
char
save_cmos_A; char save_cmos_B;
int
init_module(void) { char ctemp; rtf_create(0, 4000);
/*
turn the speaker on: */ /* set the output of 8354's channel 2 to 1
*/ outb_p(inb_p(0x61)|3, 0x61); outb_p(0xb0, 0x43); outb_p(3,
0x42); outb_p(0, 0x42);
request_RTirq(CMOS_IRQ,
intr_handler);
save_cmos_A = CMOS_READ(RTC_REG_A); save_cmos_B =
CMOS_READ(RTC_REG_B);
/* 32 kHz base; interrupt at 8192 Hz
*/ CMOS_WRITE(0x23, RTC_REG_A);
/* enable periodic interrupts
*/ ctemp = CMOS_READ(RTC_REG_B); ctemp &= 0x8f; ctemp |=
0x40; CMOS_WRITE(ctemp, RTC_REG_B);
(void)
CMOS_READ(RTC_REG_C); /* Clear the interrupt */
return 0; }
void
cleanup_module(void) { rtf_destroy(0); CMOS_WRITE(save_cmos_A,
RTC_REG_A); CMOS_WRITE(save_cmos_B, RTC_REG_B); free_RTirq(8); } |