Dear forum,

We are working on a set of Java Native Interface hooks to allow java
programs to have access to shared memory and realtime FIFO's to allow
communication between RTLinux space and a Java VM.

We have currently implemented code that allows java to read and write to
a integer held in shared memory.  The code to do this and some sample
java code is attached.

This could allow people to create networked / graphical front ends to
RTLinux programs very easily.  For many high level, non realtime tasks
the java environment provides the easiest and quickest development
environment.

We are interested to find out if there is any interest / demand for this
code as it could easily be written to allow access to all type of
RTLinux / Linux communications paths.  We would also appreciate any
comments regarding to the structure of the code and improvements that
could be made.

The files are as follows:
RTL_SharedMemInt.java - Java library for accessing shared memory
integers
RTL_SharedMemInt.h - Header file for implementing Java Native Calls
RTL_SharedMemInt.c - Header file for implementing Java Native Calls, to
be compiled to libRTL_SharedMemInt.so
realtime_module.c - A test realtime module
SharedMemTest.java - A terminal based java test program
SharedMemApplet.java - A applet based java test program
Makefile - makefile for compiling RTL_SharedMemInt.c (check library
locations to suit your machine for realtime and java paths)

The sample program creates a thread that increments an int variable
every second (realtime) and the value of this variable is accessed from
java space.


Kelvin Proctor & Robert Reid
University of NSW
Sydney, Australia
libRTL_SharedMemInt.so : 
        gcc -Wall -shared -I/usr/src/linux/rtlinux -I/usr/include 
-I/usr/local/PACKAGES/jdk118_v1_bd/include 
-I/usr/local/PACKAGES/jdk118_v1_bd/include/linux -o libRTL_SharedMemInt.so 
RTL_SharedMemInt.c
#include <stdio.h>
#include <rtlinux/mbuff.h>
#include "RTL_SharedMemInt.h"

/*
 * Class:     RTL_SharedMemInt
 * Method:    readInt
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_RTL_1SharedMemInt_readInt (JNIEnv *env , jobject obj, 
jstring _tagname) {

  const jbyte *tagname; /* jbyte is signed 8 bit */
  volatile int* value;
  jint return_value; /* jint is 32 bit signed integer */

  /* Get the name of tag from a java.lang.String to
     a standard c string */
  tagname = (*env)->GetStringUTFChars(env,_tagname,NULL);
  if (tagname == NULL) {
    return NULL; /* Exception will have been thrown */
  }

  /* Create reference to shared memory object as an int */
  value = (volatile int*) mbuff_alloc(tagname, 1024);

  /* cast int value to a java int */
  return_value = (jint) *value;

  /* Release reference to the tagname from java enviroment */
  (*env)->ReleaseStringUTFChars(env,_tagname,tagname);

  /* destroy the reference to the shared memory object */
  mbuff_free(tagname,(void *)value);

  return return_value;

}

/*
 * Class:     RTL_SharedMemInt
 * Method:    writeInt
 * Signature: (Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_RTL_1SharedMemInt_writeInt (JNIEnv *env, jobject obj, 
jstring _tagname, jint _value) {

  const jbyte *tagname; /* jint is 32 bit signed integer */
  volatile int* variable;

  /* Get the name of tag from a java.lang.String to
     a standard c string */
  tagname = (*env)->GetStringUTFChars(env,_tagname,NULL);
  if (tagname == NULL) {
    return; /* Exception will have been thrown */
  }

  /* Create reference to shared memory object as an int */
  variable = (volatile int*) mbuff_alloc(tagname, 1024);

  /* cast jint value to an int and write to shared memory */
  *variable = (int) _value;

  /* Release reference to the tagname from java enviroment */
  (*env)->ReleaseStringUTFChars(env,_tagname,tagname);

  /* destroy the reference to the shared memory object */
  mbuff_free(tagname,(void *)variable);

}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class RTL_SharedMemInt */

#ifndef _Included_RTL_SharedMemInt
#define _Included_RTL_SharedMemInt
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     RTL_SharedMemInt
 * Method:    readInt
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_RTL_1SharedMemInt_readInt
  (JNIEnv *, jobject, jstring);

/*
 * Class:     RTL_SharedMemInt
 * Method:    writeInt
 * Signature: (Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_RTL_1SharedMemInt_writeInt
  (JNIEnv *, jobject, jstring, jint);

#ifdef __cplusplus
}
#endif
#endif
/* Java class to allow interaction between RTLinux and Java
 * 
 * This class will allow access to an integer variable kept in
 * shared memory by RTLinux.  The viable must already exist in
 * RTLinux space on an exception will occur.
 *
 * Due to the limitations that there is no destructor function
 * in Java a new reference to the Shared Memory object must be
 * created each time the variable.
 *
 * Since the 32 bit signed integer format from java may not map
 * to a c/c++ int primitive an explicate cast is made and there
 * is the possibility of data loss/truncation 
 *
 * Authors: Kelvin Proctor
 *          Robert Reid
 * Created: 24/8/2000
 * Modified: 27/8/2000
 */

public class RTL_SharedMemInt {
        static {
                System.loadLibrary("RTL_SharedMemInt");
        }
        
        private String tagname;
        
        public RTL_SharedMemInt(String _tagname) {
                tagname = _tagname;
        }
        
        private native int readInt(String name);
        private native void writeInt(String name, int value);

        public int RTL_readInt() {
                return readInt(tagname);
        }

        public void RTL_writeInt(int value) {
                writeInt(tagname, value);
        }
}

public class ShareMemTest {

    public static void main(String args[]) {

        RTL_SharedMemInt sm = new RTL_SharedMemInt("counter");

        while (true) {
            System.out.println(sm.RTL_readInt());
            try {
                Thread.sleep(1000);
            } catch (Exception e) {}
        }
    }
}
#include <rtlinux/rtl_sched.h>
#include <linux/module.h>
#include <pthread.h>
#include <rtlinux/rtl_printf.h>
#include <rtlinux/rtl_time.h>
#include <rtlinux/mbuff.h>

volatile int* count;

void *task1_function(void *arg);

pthread_t thread1;

int init_module(void) {
  
  count = (volatile int*) mbuff_alloc("counter", 1024);
  *count = 0;
 
  /* create task 1 */
  pthread_create (&thread1, NULL, task1_function, NULL);

  return 0;

}

int cleanup_module(void) {

  /* kill task 1 */
  pthread_delete_np(thread1);

  mbuff_free("counter",(void *)count);

  return 0;
  
}

void *task1_function(void *arg) {

  hrtime_t now = gethrtime();
  hrtime_t period = 1000000000; /* 1 second */

  struct sched_param p;

  p.sched_priority = 1;

  pthread_setschedparam(pthread_self(), SCHED_FIFO, &p);

  pthread_make_periodic_np(pthread_self(),now+10000,period);
  
  while (1) {
    rtl_printf("Counter value is %d\n", *count);
    (*count)++;
    pthread_wait_np();
  }

  return NULL;
}
import java.applet.*;
import java.awt.*;

/* <APPLET CODE=ShareMemApplet.class WIDTH=320 HEIGHT=200></APPLET> */

public class ShareMemApplet extends Applet implements Runnable {
    Thread appletThread;
    RTL_SharedMemInt sm = new RTL_SharedMemInt("counter");

    // Update the shared memory counter
    public void paint(Graphics g) {
        g.clearRect(0,0,100,100);
        String counter = Integer.toString(sm.RTL_readInt());
        g.drawString(counter, 50,50);
    }

    // Start appletThread
    public void init() {
        if (appletThread==null) {
            appletThread = new Thread(this);
            appletThread.start();
        }
    }

    // Run will be called once appletThread has been started
    public void run() {
        while (true) {
            try { Thread.sleep(1000);
            } catch (Exception e) { }
            repaint();
        }
    }

    /*
        try { Thread.sleep(1000);
        } catch (Exception e) { }
        repaint();
     */
}

Reply via email to