Captain's Universe Home
Captain's Universe Home
Cosmic Ray Muon DetectorTeleGarden Pages
Time on MarsBryophyllum Plants
Jupiter Radio AstronomyAncient Pages
Salzburg Tourist GuideEarth Magnetometer
  H O M E     AJAX & MORE     LINUX & MORE     RTAI     XENOMAI     ADEOS IPIPE      
    JAVA & BROWSERS     *NIX     ELECTRONICS     REVIEWS     ARTEMIA     FAIRY SHRIMP      



UPDATE: Click here if you have problems with the parallel port interrupt

Parallel Port Interrupt Kernel Module Examples - Simple Device Driver:



Two kernel modules for capturing the parallel port interrupt.
First one "parlat.c" measures the parallel port interrupt latency with RTAI (real-time linux). Simple make a "null-modem" for the parallel port - connect any output pin (pin 2-9) with the IRQ pin (pin 10 = ACK). Compile the parlat module and insert it. Check the kernel log file for the generated messages.

The second example shows how to handle the par port int without hard real time - in soft real time.

Developed on kernel 2.4.25 / RTAI3.0r4 and kernel 2.6.8.1 / RTAI3.1 with gcc 3.3.4
Also tested on kernel 2.6.10 / RTAI 3.2 with gcc 2.95.4.

Note: Just ignore warnings like: *** Warning: "rt_release_irq" [...] undefined!
If the RTAI kernel modules are loaded, the symbols will resolve.

Example "parlat.c" (RTAI hard real time)
#include <linux/module.h>
#include <rtai.h>
#include <rtai_sched.h>

#define BASEPORT 0x378

static int time;
static int time2;
static int timex;
static int timex2;

static void handler(void)
{
	int timediff;
	time2 = rt_get_time_ns();
	timex2 = rt_get_cpu_time_ns();
	timediff = time2 - time;
	rt_printk(">>> interrupt latency = %d ns\n", timediff);
	timediff = timex2 - timex;
	rt_printk(">>> interrupt latency = %d ns\n", timediff);
	rt_ack_irq(7);
}

int xinit_module(void)
{
	int ret;
	ret = rt_request_global_irq(7, (void *)handler);
	rt_enable_irq(7);
	outb_p(0x10, BASEPORT + 2); //set port to interrupt mode; pins are output

	rt_printk("Generating interrupt now on all output pins (intr/ACK = pin 10)\n");
	
	//generate interrupt
	outb_p(0, BASEPORT);
	rt_set_oneshot_mode();
	time = rt_get_time_ns();
	timex = rt_get_cpu_time_ns();
	outb_p(255, BASEPORT);
	outb_p(0, BASEPORT);
	rt_printk("Interrupt generated. You should see the latency message\n");
	return 0;
}

void xcleanup_module(void)
{
	rt_printk("Unloading  parallel port latency test\n");
	rt_disable_irq(7);
	rt_free_global_irq(7);
}

module_init(xinit_module);
module_exit(xcleanup_module);
MODULE_LICENSE("GPL");
Makefile for parlat.c: (kernel 2.4)
TARGET	:= parlat
INCLUDE	:= -I/lib/modules/`uname -r`/build/include -I/usr/realtime/include
CFLAGS	:= -O2 -Wall -DMODULE -DUSEFIFO -D__KERNEL__ -DLINUX
CC	:= gcc

${TARGET}.o: ${TARGET}.c
	$(CC) $(CFLAGS) ${INCLUDE} -c ${TARGET}.c
Makefile for parlat.c: (kernel 2.6)
obj-m	:= parlat.o

KDIR	:= /lib/modules/$(shell uname -r)/build
PWD	:= $(shell pwd)
EXTRA_CFLAGS := -I/usr/realtime/include -I/usr/include/

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Insert the modules with: (kernel 2.4)
#!/bin/sh

TMP=$PWD
cd /usr/realtime/modules/

check=`lsmod | grep -c "^rtai_hal"`
if [ $check == 0 ]
then
	insmod ./rtai_hal.o
fi

check=`lsmod | grep -c "^rtai_ksched"`
if [ $check == 0 ]
then
	insmod ./rtai_ksched.o
fi

cd $TMP

check=`lsmod | grep -c "^rt_process"`
if [ $check == 0 ]
then
	insmod ./parlat.o
else
	rmmod parlat
	insmod ./parlat.o
fi
Insert the modules with: (kernel 2.6)
#!/bin/sh
TMP=$PWD
cd /usr/realtime/modules/

check=`lsmod | grep -c "^rtai_hal"`
if [ $check == 0 ]
then
	insmod ./rtai_hal.ko
fi

check=`lsmod | grep -c "^rtai_up"`
if [ $check == 0 ]
then
	insmod ./rtai_ksched.ko
fi

cd $TMP

check=`lsmod | grep -c "^rt_process"`
if [ $check == 0 ]
then
	insmod ./parlat.ko
else
	rmmod parlat
	insmod ./parlat.ko
fi
Remove the modules with:
#!/bin/sh
rmmod parlat
rmmod rtai_ksched
#rmmod rtai_up
rmmod rtai_hal




Example "parint.c" (soft real-time):
#include <linux/module.h>
#include <linux/interrupt.h>
#include <asm/io.h>

#define BASEPORT 0x378

static int handler(void)
{
	// do stuff
	printk(">>> PARALLEL PORT INT HANDLED\n");
	return IRQ_HANDLED;
}

int xinit_module(void)
{
	int ret;
	ret = request_irq(7, handler, SA_INTERRUPT, "parallelport", NULL);
	enable_irq(7);

	//set port to interrupt mode; pins are output
	outb_p(0x10, BASEPORT + 2); 

	printk("Generating interrupt now on all output pins (intr/ACK = pin 10)\n");
	
	//generate interrupt
	outb_p(0, BASEPORT);
	outb_p(255, BASEPORT);
	outb_p(0, BASEPORT);
	printk("Interrupt generated. You should see the handler-message\n");
	return 0;
}

void xcleanup_module(void)
{
	disable_irq(7);
	free_irq(7, NULL);
}

module_init(xinit_module);
module_exit(xcleanup_module);
MODULE_LICENSE("GPL");
Makefile for parint.c: (kernel 2.4)
TARGET	:= parint
INCLUDE	:= -I/lib/modules/`uname -r`/build/include
CFLAGS	:= -O2 -Wall -DMODULE -D__KERNEL__ -DLINUX
CC	:= gcc

${TARGET}.o: ${TARGET}.c
	$(CC) $(CFLAGS) ${INCLUDE} -c ${TARGET}.c
Makefile for parint.c: (kernel 2.6)
obj-m	:= parint.o

KDIR	:= /lib/modules/$(shell uname -r)/build
PWD		:= $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Insert the module with: (kernel 2.4)
# insmod ./parint.o
Insert the module with: (kernel 2.6)
# insmod ./parint.ko
Remove the module with:
# rmmod parint


Last-Modified: Tue, 17 Jun 2008 18:30:08 GMT

Google
 
Web www.captain.at
go to top
© 1996-2010 . All rights reserved.
No reproduction, distribution, publishing or transmission of the copyrighted materials at this site is permitted. Policy
go to top