A Linux-based Real-Time Operating System #3

Home Up

 

 

References

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);
}