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      


Adeos Nano Kernel Linux Hard Real Time Parallel Port Interrupt Handler Kernel Module - standalone version

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.

UPDATE: If you don't have an APIC on your system, check this page ADEOS IPIPE Hard Real Time - 8254 Timer Programming


This example is basically the same as Adeos Parallel Port Interrupt with the difference that this example also captures the timer interrupt to generate a square wave signal on the parallel port data pins. This square wave signal is used to trigger the parallel port interrupt itself, so that our parallel port ISR is triggered.

For RTAI/fusion and RTAI/classic examples see:
RTAI/fusion Parallel Port Interrupt ISR
RTAI Parallel Port Interrupt - LXRT
For the extended standalone version (with APIC setup and /proc file read/write capability) see:
Adeos Parallel Port Interrupt - extended standalone version

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 and you'll see an output like this in your kernel log file:
Jul 10 15:28:40 localhost kernel: Adeos: Domain TestDomain registered.
Jul 10 15:28:40 localhost kernel: Domain TestDomain started.
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=0
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=1
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=2
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=3
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=4
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=5
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=6
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=7
Jul 10 15:28:40 localhost kernel: >>> PARALLEL PORT INT HANDLED: counter=8
Jul 10 15:29:13 localhost kernel: Adeos: Domain TestDomain unregistered.



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;
static adsysinfo_t sys_info;
int parcounter = 0;
long long timercounter = 0;

void handler(unsigned irq) {
	printk(">>> PARALLEL PORT INT HANDLED: counter=%d\n", parcounter);
	parcounter++;
	adeos_control_irq(PAR_INT,0,IPIPE_ENABLE_MASK);
	adeos_propagate_irq(irq);
}
void timer_tick (unsigned irq) {
	timercounter++;
	if (timercounter < 10) {
		outb_p(0, BASEPORT);
		outb_p(255, BASEPORT);
	}
	adeos_propagate_irq(irq);
}
void domain_entry (int iflag) {
	printk("Domain %s started.\n",adp_current->name);

	if (iflag) {
		adeos_get_sysinfo(&sys_info);
		// tmirq = timer irq
		adeos_virtualize_irq(sys_info.archdep.tmirq,
			&timer_tick, NULL, IPIPE_DYNAMIC_MASK);
		// parallel port irq
		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: Thu, 14 Sep 2006 18:31:58 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