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      


RTAI/fusion Pipe (FIFO) Kernel Module Example

Also see Porting software from RTAI/fusion to Xenomai

This is a simple RTAI/fusion hard real time pipe (FIFO) example (based on the snippets "showroom" in [fusion-dir]/skins/rtai/snippets/pipe.c). pipe.c is the kernel module, which opens the pipe (FIFO) /dev/rtf0 for reading and writing in kernel space. user.c is the user-space program, which also reads and writes from/to the pipe.


Compile the program "pipe.c" and "user.c" with "make" (Makefile below).
Run "user" and - in another shell - load the fusion modules with "loadmods.sh" and the pipe kernel module with "insmod ./pipe.ko".
# ./user
read from pipe: Hello
written string 'World' - see kernel log

In the kernel log you'll see:
Jul 31 21:09:52 muon kernel: INIT DONE
Jul 31 21:09:52 muon kernel: received msg> World, size=6
Jul 31 21:10:00 muon kernel: CLEANUP DONE


If you get a compilation error like this
timer.c: In function `main':
*timer.c:45: warning: implicit declaration of function `rt_task_spawn'
/tmp/ccIQ6xk6.o(.text+0x129): In function `main':
: undefined reference to `rt_task_spawn'
collect2: ld returned 1 exit status*
make: *** [timer] Error 1
you need to upgrade to a recent version of RTAI/fusion (0.8.3 as of writing this). rt_task_spawn was added in version 0.7.3.
rt_task_spawn() is actually a combination of rt_task_create() and rt_task_start().

The warnings about the undefined symbols can be ignored. The symbols will resolve as soon as the fusion kernel modules are loaded with "loadmods.sh":
# make
make -C /lib/modules/2.6.12.3-adeos-fusion/build SUBDIRS=/home/fusion/kernelpipe modules
make[1]: Entering directory `/usr/src/linux-2.6.12.3-fusion'
  CC [M]  /home/fusion/kernelpipe/pipe.o
  Building modules, stage 2.
  MODPOST
*** Warning: "rt_task_delete" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_pipe_delete" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_task_start" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_task_create" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_pipe_create" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_pipe_free" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_pipe_receive" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_pipe_send" [/home/fusion/kernelpipe/pipe.ko] undefined!
*** Warning: "rt_pipe_alloc" [/home/fusion/kernelpipe/pipe.ko] undefined!
  LD [M]  /home/fusion/kernelpipe/pipe.ko
make[1]: Leaving directory `/usr/src/linux-2.6.12.3-fusion'
gcc -o user user.c -I/usr/realtime/include


pipe.c

#include <linux/module.h>
#include <rtai/task.h>
#include <rtai/pipe.h>

#define PIPE_MINOR 0

#define TASK_PRIO  2               /* Highest RT priority */
#define TASK_MODE  T_FPU|T_CPU(0)  /* Uses FPU, bound to CPU #0 */
#define TASK_STKSZ 4096            /* Stack size (in bytes) */

RT_TASK task_desc;
RT_PIPE pipe_desc;

void task_body (void *cookie) {
    RT_PIPE_MSG *msgout, *msgin;
    int len = sizeof("Hello");
    /* Get a message block of the right size in order to initiate the
       message-oriented dialog with the user-space process. Sending a
       continuous stream of bytes is also possible using
       rt_pipe_stream(), in which case no message buffer needs to be
       preallocated. */
    msgout = rt_pipe_alloc(len);

    if (msgout) {

		// Send prompt message "Hello"
		strcpy( P_MSGPTR(msgout), "Hello");
		//rt_pipe_send(&pipe_desc, msgout, len, P_NORMAL);
		if (rt_pipe_send(&pipe_desc, msgout, len, 0) != len) {
			rt_pipe_free(msgout);
		}

		// Then wait for the reply string "World":
		rt_pipe_receive(&pipe_desc, &msgin, TM_INFINITE);
		printk("received msg> %s, size=%d\n",P_MSGPTR(msgin),P_MSGSIZE(msgin));
		// Free the received message buffer.
		rt_pipe_free(msgin);

	} else {
		printk("ERROR: rt_pipe_alloc\n");
	}
}

int __init init_module (void) {
	int err;
	err = rt_pipe_create(&pipe_desc, "pipetest", PIPE_MINOR);
	if (!err) {
		err = rt_task_create(&task_desc, "MyTaskName", TASK_STKSZ, TASK_PRIO, TASK_MODE);
		if (!err) {
			rt_task_start(&task_desc, &task_body, NULL);
		} else {
			printk("ERROR: cannot create task\n");
			return 0;
		}
/*		// since fusion 0.7.3 you can also use rt_task_spawn
		err = rt_task_spawn(&task_desc, "MYTask", TASK_STKSZ, TASK_PRIO, 0, &task_body, NULL);
		if (err) {
			printk("error rt_task_spawn\n");
			return 0;
		}	
*/
	} else {
		printk("ERROR: cannot create pipe\n");
	}
	printk("INIT DONE\n");
	return 0;
}

void __exit cleanup_module (void) {
    rt_pipe_delete(&pipe_desc);
    rt_task_delete(&task_desc);
    printk("CLEANUP DONE\n");
}

MODULE_LICENSE("GPL");

user.c

#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <rtai/pipe.h>

#define PIPE_MINOR 0

int pipe_fd;

int main (int argc, char *argv[]) {
	char devname[32], buf[16];
	sprintf(devname, "/dev/rtp%d", PIPE_MINOR);
	pipe_fd = open(devname, O_RDWR);
    
	if (pipe_fd < 0) {
		printf("cannot open pipe %s\n", devname);
		exit(1);
	}

	read(pipe_fd, buf, sizeof(buf));
	printf("read from pipe: %s\n", buf);
	
	write(pipe_fd, "World", sizeof("World"));
	printf("written string 'World' - see kernel log\n");
	
	close(pipe_fd);
}

loadmods.sh

#!/bin/sh
TMP=$PWD
cd /usr/realtime/modules/
insmod ./rtai_hal.ko
insmod ./rtai_nucleus.ko
insmod ./rtai_native.ko
cd $TMP

Makefile

obj-m	:= pipe.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
	gcc -o user user.c -I/usr/realtime/include
Last-Modified: Sat, 04 Feb 2006 16:06:01 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