Adeos Nano Kernel Hard Real Time Parallel Port Interrupt Handler Kernel Module
This example show how to capture the parallel port interrupt with an ADEOS (www.adeos.org) patched vanilla Linux kernel.
Using the Adeos nano kernel makes this example running in hard real time, since the Linux kernel is running only
as Adeos idle task. This means, if there is nothing to do in any Adeos domain, Linux can do it's stuff.
For a standalone version (with a square wave generator for the par port) see:
Adeos Parallel Port Interrupt - standalone version
For the extended standalone version (with APIC setup and /proc file read/write capability) see:
Adeos Parallel Port Interrupt - extended standalone version
For RTAI/fusion and RTAI/classic examples see:
RTAI/fusion Parallel Port Interrupt ISR
RTAI Parallel Port Interrupt - LXRT
For a method on how to read data from kernel space in user space see:
Linux Device Driver Kernel Module FIFO (circular buffer)
Adeos Nano Kernel Hard Real Time Double Buffering FIFO
Compile "parint.c" with "make".
Make a "null-modem" for the parallel port - connect any output pin (pin 2-9) with the IRQ pin (pin 10 = ACK).
Load the kernel module. Use gen.sh (at the bottom of the page)
to generate some parallel port interrupts and you'll see an output like this in your kernel log file:
Jul 10 03:04:10 localhost kernel: Adeos: Domain TestDomain registered.
Jul 10 03:04:10 localhost kernel: Domain TestDomain started.
Jul 10 03:04:13 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=0
Jul 10 03:04:13 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=1
Jul 10 03:04:13 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=2
Jul 10 03:04:18 localhost kernel: Adeos: Domain TestDomain unregistered.
Also check the Adeos proc entry:
# cat /proc/adeos
Adeos 2.4r18c1/x86 -- Pipelining: permanent
TestDomain: priority=101, id=0x00000001, ptdkeys=0/83443
irq0-6: passed
irq7: grabbed
irq8-206: passed
irq207: grabbed
irq208-223: passed
irq224: passed, virtual
Linux: priority=100, id=0x00000000, ptdkeys=0/4
irq0-15: accepted
irq16-190: passed
irq191-218: accepted
irq219-223: passed
irq224: grabbed, virtual
You will see the Linux domain with a priority of 100, and our Testdomain with a higher priority of 101.
parint.c
#include <linux/version.h>
#include <linux/module.h>
#include <asm/io.h>
#define BASEPORT 0x378
#define PAR_INT 7
static adomain_t this_domain;
int counter = 0;
void handler(unsigned irq) {
printk(">>> PARALLEL PORT INT HANDLED: counter=%d\n", counter);
counter++;
adeos_control_irq(PAR_INT,0,IPIPE_ENABLE_MASK);
adeos_propagate_irq(PAR_INT);
}
void domain_entry (void) {
printk("Domain %s started.\n",adp_current->name);
adeos_virtualize_irq(PAR_INT,&handler,NULL,IPIPE_DYNAMIC_MASK);
//set port to interrupt mode; pins are output
outb_p(0x10, BASEPORT + 2);
adeos_control_irq(PAR_INT,0,IPIPE_ENABLE_MASK);
for (;;)
// This domain's idle loop
adeos_suspend_domain(); // control back to ADEOS
}
static int __init mod_init (void) {
adattr_t attr;
attr.name = "TestDomain";
attr.domid = 1; // Adeos Domain ID: >0
attr.entry = &domain_entry;
attr.estacksz = 0; // Adeos chooses a reasonable stack size
attr.priority = ADEOS_ROOT_PRI + 1;
attr.dswitch = NULL; // Domain switch hook - always a C routine
return adeos_register_domain(&this_domain,&attr);
}
static void __exit mod_exit (void) {
adeos_unregister_domain(&this_domain);
}
module_init(mod_init);
module_exit(mod_exit);
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: Sat, 04 Feb 2006 15:44:16 GMT