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      



Parallel port frequency test of RTAI - Hard real time test

These examples are a demonstration for hard real time.
Compile both examples, hook up a frequency counter on any data pin (pin 2-9) at the parallel port (0x378) and run "start.sh". See what frequency you're getting with the real time kernel module (should be 10kHz). In another shell do something CPU intensive like updatedb or compiling something big. You will see that the frequency stays a 10kHz.

Issue ./stop.sh and run "rect". See again what frequency you're getting (about 1kHz in my case) and then do something CPU intensive. You will see that the frequency drops and jumps around, depending on the current CPU load.

Tested on kernel 2.6.7 and vesuvio (hal6c1-2.6.7.patch) on Fedora Core 2 and kernel 2.4.25 and rtai-3.0r4 on debian sarge (testing release)

myrt_process.c - our kernel module
#include <linux/module.h>
#include <rtai.h>
#include <rtai_sched.h>

#define TICK_PERIOD 50000
#define TASK_PRIORITY 1
#define STACK_SIZE 10000
#define BASEPORT 0x378

static RT_TASK rt_task;
static RTIME tick_period;

static void fun(int t)
{
	while (1) {
		outb(0, BASEPORT);
		rt_task_wait_period();
		outb(255, BASEPORT);
		rt_task_wait_period();
	}
}

int xinit_module(void)
{
	outb(0, BASEPORT + 2); //set port to output mode
	//RTIME tick_period;
	rt_set_periodic_mode();
	rt_task_init(&rt_task, fun, 1, STACK_SIZE, TASK_PRIORITY, 1, 0);
	tick_period = start_rt_timer(nano2count(TICK_PERIOD));
	rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period);
	return 0;
}

void xcleanup_module(void)
{
	stop_rt_timer();
	rt_task_delete(&rt_task);
	return;
}

module_init(xinit_module);
module_exit(xcleanup_module);
MODULE_LICENSE("GPL");
Makefile for the kernel module (kernel 2.6)
obj-m	:= myrt_process.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
Makefile for the kernel module (kernel 2.4)
TARGET	:= myrt_process
INCLUDE	:= -I/lib/modules/`uname -r`/build/include -I/usr/realtime/include
CFLAGS	:= -O2 -Wall -DMODULE -D__KERNEL__ -DLINUX
CC	:=  gcc

${TARGET}.o: ${TARGET}.c
	$(CC) $(CFLAGS) ${INCLUDE} -c ${TARGET}.c
start.sh to insert the modules and start our kernel module (for kernel 2.6)
#!/bin/sh
TMP=$PWD
cd /usr/realtime/modules/
insmod ./rtai_hal.ko
insmod ./rtai_ksched.ko
cd $TMP
insmod ./myrt_process.ko
start.sh for kernel 2.4
#!/bin/sh
TMP=$PWD
cd /usr/realtime/modules/
insmod rtai_hal.o
insmod rtai_ksched.o
cd $TMP
insmod myrt_process.o
stop.sh to remove the modules
#!/bin/sh
rmmod myrt_process
rmmod rtai_up
rmmod rtai_ksched
rmmod rtai_hal
(on kernel 2.6 rtai_up is listed via "lsmod"; on kernel 2.4 it is rtai_ksched, so we try to remove both)



User-space test rect.c:
call updatedb or something CPU intensive to see the frequency changing on the parallel port
Compile with: # gcc -O2 -o rect rect.c
#include <stdio.h>
#include <stdlib.h>
#include <asm/io.h>
#include <signal.h>

#define BASEPORT 0x378

static int end;

static void endme(int dummy)
{
	end=1;
}

int main(int argc, char **argv) {

	if (ioperm(BASEPORT, 3, 1)) {  	
			// ask for permissions to access the parallel port
			// YOU MUST BE ROOT TO ASK FOR THIS SORT OF PERMISSION, so
			//     don't forget to 'su' yourself ;-)
			// usage of ioperm: BASEPORT ... base address we want to use
			//		3 ... the next 3 bytes
			//		1 ... we want the permission
		perror("ioperm open");
		exit(1);
	}

	signal(SIGINT, endme);

	outb(0, BASEPORT + 2); // set to output mode

	while (!end) {   // adjust usleep if you want
		usleep(0);
		outb(0, BASEPORT);
		//usleep(0);
		outb(255, BASEPORT);
	}
	freeperm(); // tell the system we do not use the port anymore

	exit(0);
}

int freeperm() {
	if (ioperm(BASEPORT, 3, 0)) { 
		// tell the system we do not use the port anymore
		// usage of ioperm: BASEPORT ... base address we want to use
		//					3 ... the next 3 bytes
		//					0 ... free the permission	
		perror("ioperm close");
	}
}



Last-Modified: Sat, 04 Feb 2006 16:13:49 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