JavaによるVMEアクセス
Java言語を使ってVMEへアクセスする方法を提供します。そのためには
まずJavaの開発環境を整える必要があります。
Java2 Platform, standard editonを
SunのJavaサイトからダウンロードし、整備します。
それが済んだら、C言語で書かれたVMEライブラリをダウンロードし、整備します。
ここでは
KEK標準VMEライブラリを用います。
それが済めばいよいよJava Native Interface(JNI)プログラムの書き方に入ります。
KEK標準VMEライブラリは下記のJavaメソッドによりアクセスされます。
- public synchronized native int mapOpen(int mode, int vmeaddr, int size);
- public synchronized native int mapClose(int viraddr, int mode);
- public synchronized native void writeByte(int viraddr, byte data);
- public synchronized native void writeShort(int viraddr, short data);
- public synchronized native void writeInt(int viraddr, int data);
- public synchronized native byte readByte(int viraddr);
- public synchronized native short readShort(int viraddr);
- public synchronized native int readInt(int viraddr);
この中で、mapOpenとmapCloseメソッドはVMEライブラリの下記の関数を
直接呼んでいます。
- caddr_t vme_mapopen(int mode, caddr_t vmeaddr, size_t size);
- int vme_mapclose(int mode);
通常C言語では関数を使わずポインタを利用してVMEへアクセスするので
特に関数は用意されていませんが、Javaの場合はポインタを利用した
VMEへのアクセス法は許していませんので、Javaのためにメソッドが
必要になります。上記のその他のJavaメソッドはそのような理由で
作られました。
VME.java:
public class VME {
public synchronized native int mapOpen(int mode, int vmeaddr, int size);
public synchronized native int mapClose(int viraddr, int mode);
public synchronized native void writeByte(int viraddr, byte data);
public synchronized native void writeShort(int viraddr, short data);
public synchronized native void writeInt(int viraddr, int data);
public synchronized native byte readByte(int viraddr);
public synchronized native short readShort(int viraddr);
public synchronized native int readInt(int viraddr);
static {
System.loadLibrary("JavaVME");
}
}
#include
#include "VME.h"
#include "vmelib.h"
int vme_mapopen( jint mode, jint vmeaddr, jint size);
int vme_mapclose( jint viraddr, jint mode);
void writeByte( jint viraddr, jbyte data);
void writeShort( jint viraddr, jshort data);
void writeInt( jint viraddr, jint data);
jbyte readByte( jint viraddr );
jshort readShort( jint viraddr );
jint readInt( jint viraddr );
JNIEXPORT jint JNICALL
Java_VME_mapOpen(JNIEnv *env, jobject obj, jint mode, jint vmeaddr, jint size) {
return vme_mapopen( mode, vmeaddr, size);
}
JNIEXPORT jint JNICALL
Java_VME_mapClose(JNIEnv *env, jobject obj, jint viraddr, jint mode) {
return vme_mapclose(viraddr, mode);
}
JNIEXPORT void JNICALL
Java_VME_writeByte(JNIEnv *env, jobject obj, jint viraddr,
jbyte data) {
jbyte *data_pointer = (jbyte *)viraddr;
*data_pointer = data;
}
JNIEXPORT void JNICALL
Java_VME_writeShort(JNIEnv *env, jobject obj, jint viraddr,
jshort data) {
jshort *data_pointer = (jshort *)viraddr;
*data_pointer = data;
}
JNIEXPORT void JNICALL
Java_VME_writeInt(JNIEnv *env, jobject obj, jint viraddr,
jint data) {
jint *data_pointer = (jint *)viraddr;
*data_pointer = data;
}
JNIEXPORT jbyte JNICALL
Java_VME_readByte(JNIEnv *env, jobject obj, jint viraddr) {
jbyte *data_pointer = (jbyte *)viraddr;
return *data_pointer;
}
JNIEXPORT jshort JNICALL
Java_VME_readShort(JNIEnv *env, jobject obj, jint viraddr) {
jshort *data_pointer = (jshort *)viraddr;
return *data_pointer;
}
JNIEXPORT jint JNICALL
Java_VME_readInt(JNIEnv *env, jobject obj, jint viraddr) {
jint *data_pointer = (jint *)viraddr;
return *data_pointer;
}
SHELL = /bin/sh
JC = javac
JH = javah
CC = gcc
JFLAGS = -O
CFLAGS = -O -shared -Wall
JINCLUDE= -I/usr/local/src/jdk1.3/include -I/usr/local/src/jdk1.3/include/linux
CINCLUDE= -I../vmelib/include -I.
INCLUDE = $(JINCLUDE) $(CINCLUDE)
LIBDIR = ../lib
CLASSDIR= ../classes
CAMLIB = ../vmelib/lib
CLASS = VME
STUB = VME.class
LIBRARY = libJavaVME.so
all : stub lib
clean :
rm -f \#* *~ rm -f *.class $(CLASS).c $(CLASS).h libJavaVME.so
rm -f $(CLASSDIR)/$(CLASS).class
rm -f $(LIBDIR)/$(LIBRARY)
stub : $(CLASSDIR)/$(CLASS).class
lib : $(CLASS).class $(CLASS).imp.c
$(CC) -o $(LIBRARY) $(CFLAGS) $(INCLUDE) $(CLASS).imp.c \
-L$(CAMLIB) -lvmelib
cp -p $(LIBRARY) $(LIBDIR)
$(CLASSDIR)/$(CLASS).class : $(CLASS).java
$(JC) $(JFLAGS) $(CLASS).java
$(JH) -jni $(CLASS)
if [ ! -e $(CLASS).imp.c ] ; then touch $(CLASS).imp.c ; fi
if [ ! -e $(CLASS).imp.h ] ; then touch $(CLASS).imp.h ; fi
cp -p $(CLASS).class $(CLASSDIR)
上記のMakefileは下記のファイル群を利用しています。
src:
Makefile VME.imp.c VME.imp.h VME.java
vmelib:
doc/ example/ include/ lib/
doc:
README install.txt usage.html
example:
Makefile dmatest* intreg.c intreg2.c vscaler.h
Makefile.orig dmatest.c intreg.h vscaler.c
include:
vme_common.h vme_config.h vmelib.h
lib:
Makefile libvmelib.a vmelib.c vmelib.o
上記のディレクトリ中に含まれるdmaxxxはVMEのDMAをサポートする
関数群ですが、ここでは扱っていません。
class ForceMemTest{
public static void main(String argv[]){
int a16d16mode = 1;
int a16d32mode = 2;
int a24d16mode = 3;
int a24d32mode = 4;
int a32d32mode = 5;
int a32d16mode = 6;
int vme_addr = 0x11000000;
int vir_addr;
int status, data;
int length = 240;
VME vme = new VME();
vir_addr = vme.mapOpen(a32d32mode, vme_addr, length);
System.out.println("mapOpen : virtual address =" + vir_addr);
for( int i = 0; i < 1; i++)
for( int j = 0; j < length/4; j++ ) {
vme.writeInt(vir_addr, j);
data = vme.readInt(vir_addr);
if( data != j ) {
System.out.println("Written data = "+j+" Read Data = "+data);
break;
}
}
status = vme.mapClose(vir_addr, length);
System.out.println("mapClose : status =" + status);
}
}
さて例題をコンパイルし実行させるためにはJavaの開発環境を整備する
必要があります。大事な環境変数である、CLASSPATH, LD_LIBRARY_PATHを
セットします。
以下はこの例題を実行させるために必要な手続きです。
setup.csh:
#!/bin/csh
setenv CLASSPATH $CLASSPATH\:/home/yasu/java/vme/classes\:/home/yasu/java/vme/examples\:/usr/local/java/vme/lib
setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH\:/home/yasu/java/vme/lib
このコマンドを実行させてから上記のテストプログラムを走らせます。
% ./setup.csh
% javac ForceMemTest
% java ForceMemTest