Jan 16, 2003
onlsbc1, Red Hat Linux 8.0 のシステムでのJNIの実行
--- ネイティブコードでのarrayデータの受け渡し #8
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(http://www-online.kek.jp/~inoue/para-CAMAC/
Work/SBC-Java10.html)
高エネルギー加速器研究機構
素粒子原子核研究所
物理、オンライングループ
井上 栄二
目的
SBC、PCM-9370にインストールしてある Red Hat Linux 8.0 のシステム上で
JNIを使ってarrayデータの受け渡しを確認をする。 これは、Javaメソッド
からCAMACコマンドをネイティブコードに渡し、ネイティブコードで実行
したCAMACコマンドの実行結果をJavaメソッドに返す部分のテストをする
ためのものである。
(1). 構成
(2). JavaメソッドからネイティブコードにCAMACコマンドを渡す
(3). CAMACデータをネイティブコードからJavaメソッドに返す
--------------------------------------------------------------------
(1). 構成
テストに使用するマシンは onlsbc1 である。 このマシンはアドバンテク社の
SBC、PCM-9370である。 動作している OSはRed Hat Linux 8.0 で、Javaの
バージョンは1.4.1_01 である。 最終的にはコンパクトフラッシュ上に構成した
Linuxシステムで実行できることを目指すのであるが、ソフトウェアの開発段階
では 2.5" IDE ハードディスク上に構成したLinuxシステムを使ってテストを
行うことにする。
JavaメソッドはネイティブコードにCAMACコマンドを渡す。
ネイティブコードはリードデータをJavaメソッドに返す。
受け渡しは array を使用する。
並列CAMACでは64ビット長のコマンドをコントローラに渡す、コントローラは
64ビット長のリプライを返す。 しかし、SBCからPCIへのインターフェース部は 32ビット長なので
(2). JavaメソッドからネイティブコードにCAMACコマンドを渡す
(2-1). Javaのチェック
[inoue@onlsbc1 inoue]$ java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
[inoue@onlsbc1 inoue]$
(2-2). 実行環境
[inoue@onlsbc1 inoue]$ env
MANPATH=:/usr/java/man
HOSTNAME=onlsbc1.kek.jp
PVM_RSH=/usr/bin/rsh
TERM=vt100
SHELL=/bin/bash
JLESSCHARSET=japanese
HISTSIZE=1000
SSH_CLIENT=130.87.153.9 33055 22
QTDIR=/usr/lib/qt3-gcc3.2
SSH_TTY=/dev/pts/1
USER=inoue
LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;0
1:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.b
tm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:
*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*
.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;3
5:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:
PVM_ROOT=/usr/share/pvm3
MAIL=/var/spool/mail/inoue
PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/java/bin
:/home/inoue/bin
INPUTRC=/etc/inputrc
PWD=/home/inoue
LANG=ja_JP.eucJP
LAMHELPFILE=/etc/lam/lam-helpfile
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=1
HOME=/home/inoue
XPVM_ROOT=/usr/share/pvm3/xpvm
LOGNAME=inoue
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
[inoue@onlsbc1 inoue]$
(2-3). Javaコードを書く --- array を使ってネイティブコードと値を受け渡す
[inoue@onlsbc1 CmdData]$ pwd
/home/inoue/JNI/CAMAC/CmdData
[inoue@onlsbc1 CmdData]$ ls -l
合計 20
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
[inoue@onlsbc1 CmdData]$
[inoue@onlsbc1 CmdData]$ cat camac.java
// file name: camac.java
//
// Parallel camac
// packet format of basic camac opeation
// TX
// +---------+-------+-------+-------+-------+---------------------------+
// | cmd | N | A | F | | 24-bit DATA |
// +---------+-------+-------+-------+-------+---------------------------+
//
// RX
// +---------+-------+-------+-------+-------+---------------------------+
// | rply | N | A | F | ST | 24-bit DATA |
// +---------+-------+-------+-------+-------+---------------------------+
class camac {
// private native int cmdArray(int j_cmd[], int j_dat[]);
public native int cmdArray(int j_cmd[], int j_dat[]);
public static void main(String args[]) {
camac p = new camac();
int j_cmd[] = new int [10];
int j_dat[] = new int [10];
for (int i = 0; i < 10; i++){
j_cmd[i] = i;
j_dat[i] = i + 20;
}
System.out.println("Java side: before Native Call");
for (int i = 0; i < 10; i++)
System.out.println(" j_cmd[" + i + "] = " + j_cmd[i] + ", j_dat[" + i +
"] = " + j_dat[i]);
int sum = p.cmdArray(j_cmd, j_dat);
System.out.println("Java side: after Native Call");
for (int i = 0; i < 10; i++)
System.out.println(" j_cmd[" + i + "] = " + j_cmd[i] + ", j_dat[" + i +
"] = " + j_dat[i]);
}
static {
System.loadLibrary("MyImpOfcamac");
}
}
[inoue@onlsbc1 CmdData]$
(2-4). Javaコードをコンパイルする
[inoue@onlsbc1 CmdData]$ ls -l
合計 20
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
[inoue@onlsbc1 CmdData]$ make camac.class
javac camac.java
[inoue@onlsbc1 CmdData]$ ls -l
合計 24
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1112 1月 16 16:00 camac.class
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
[inoue@onlsbc1 CmdData]$
[inoue@onlsbc1 CmdData]$ javap -s -p camac
Compiled from camac.java
class camac extends java.lang.Object {
camac();
/* ()V */
public native int cmdArray(int[], int[]);
/* ([I[I)I */
public static void main(java.lang.String[]);
/* ([Ljava/lang/String;)V */
static {};
/* ()V */
}
[inoue@onlsbc1 CmdData]$
(2-5). .hファイルの生成
[inoue@onlsbc1 CmdData]$ ls -l
合計 24
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1112 1月 16 16:00 camac.class
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
[inoue@onlsbc1 CmdData]$ make camac.h
javah -jni camac
[inoue@onlsbc1 CmdData]$ ls -l
合計 28
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1112 1月 16 16:00 camac.class
-rw-rw-r-- 1 inoue inoue 384 1月 16 16:03 camac.h
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
[inoue@onlsbc1 CmdData]$
[inoue@onlsbc1 CmdData]$ cat camac.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class camac */
#ifndef _Included_camac
#define _Included_camac
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: camac
* Method: cmdArray
* Signature: ([I[I)I
*/
JNIEXPORT jint JNICALL Java_camac_cmdArray
(JNIEnv *, jobject, jintArray, jintArray);
#ifdef __cplusplus
}
#endif
#endif
[inoue@onlsbc1 CmdData]$
(2-6). C言語のソースファイルの作成
[inoue@onlsbc1 CmdData]$ ls -l
合計 28
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1112 1月 16 16:00 camac.class
-rw-rw-r-- 1 inoue inoue 384 1月 16 16:03 camac.h
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
[inoue@onlsbc1 CmdData]$ cat camac.c
/*
// file name: camac.c
//
// Parallel camac
// packet format of basic camac opeation
// TX
// +---------+-------+-------+-------+-------+---------------------------+
// | cmd | N | A | F | | 24-bit DATA |
// +---------+-------+-------+-------+-------+---------------------------+
//
// RX
// +---------+-------+-------+-------+-------+---------------------------+
// | rply | N | A | F | ST | 24-bit DATA |
// +---------+-------+-------+-------+-------+---------------------------+
*/
#include <jni.h>
#include <sys/io.h>
#include "camac.h"
/* add */
unsigned long long int value;
unsigned int camac;
/* add end */
JNIEXPORT jint JNICALL
Java_camac_cmdArray(JNIEnv *env, jobject obj, jintArray j_cmd, jintArray j_dat)
{
int i, sum = 0;
jsize len = (*env)->GetArrayLength(env, j_cmd);
jint *c_cmd = (*env)->GetIntArrayElements(env, j_cmd, 0);
jsize len2 = (*env)->GetArrayLength(env, j_dat);
jint *c_dat = (*env)->GetIntArrayElements(env, j_dat, 0);
printf("In C: Step 1\n");
for (i=0; i<len; i++) {
printf(" c_cmd[%d] = %d, c_dat[%d] = %d\n", i, c_cmd[i], i, c_dat[i])
;
}
printf("In C: Step 2\n");
for (i=0; i<len; i++) {
c_cmd[i] = c_cmd[i] + 10;
c_dat[i] = c_dat[i] - (i * 2);
}
for (i=0; i<len; i++) {
printf(" c_cmd[%d] = %d, c_dat[%d] = %d\n", i, c_cmd[i], i, c_dat[i])
;
}
printf("In C: Step 3\n");
/* add */
printf(" size of int = %d, size of long long int = %d\n", sizeof(int),
sizeof(long long int));
if( iopl(3) ){
printf("can not change the privilege level\n");
exit(0);
}
/* camac = strtoul(argv[1], NULL, 16); */
camac = 0xe800;
value = inl(camac);
printf(" 0x%x = inl(0x%x)\n", value, camac);
camac += 4;
value = inl(camac);
printf(" 0x%x = inl(0x%x)\n", value, camac);
/* add end */
printf("In C: Step 4\n");
(*env)->ReleaseIntArrayElements(env, j_cmd, c_cmd, 0);
(*env)->ReleaseIntArrayElements(env, j_dat, c_dat, 0);
return sum;
}
[inoue@onlsbc1 CmdData]$
(2-7). C言語のソースファイルをコンパイルしてシェアード・ライブラリを作成
[inoue@onlsbc1 CmdData]$ make libMyImpOfcamac.so
gcc -O -shared -I/usr/java/include -I/usr/java/include/linux camac.c -o libMyImp
Ofcamac.so
[inoue@onlsbc1 CmdData]$ ls -l
合計 36
drwxrwxr-x 2 inoue inoue 4096 1月 15 17:41 Jan15-2003
drwxrwxr-x 2 inoue inoue 4096 1月 16 13:58 Jan16-2003
-rw-rw-r-- 1 inoue inoue 316 1月 16 11:05 Makefile
-rw-rw-r-- 1 inoue inoue 2098 1月 16 14:50 camac.c
-rw-rw-r-- 1 inoue inoue 1112 1月 16 16:00 camac.class
-rw-rw-r-- 1 inoue inoue 384 1月 16 16:03 camac.h
-rw-rw-r-- 1 inoue inoue 1389 1月 16 14:49 camac.java
-rwxrwxr-x 1 inoue inoue 6848 1月 16 16:07 libMyImpOfcamac.so
[inoue@onlsbc1 CmdData]$
(2-8). 実行
[root@onlsbc1 CmdData]# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
[root@onlsbc1 CmdData]# java camac
Java side: before Native Call
j_cmd[0] = 0, j_dat[0] = 20
j_cmd[1] = 1, j_dat[1] = 21
j_cmd[2] = 2, j_dat[2] = 22
j_cmd[3] = 3, j_dat[3] = 23
j_cmd[4] = 4, j_dat[4] = 24
j_cmd[5] = 5, j_dat[5] = 25
j_cmd[6] = 6, j_dat[6] = 26
j_cmd[7] = 7, j_dat[7] = 27
j_cmd[8] = 8, j_dat[8] = 28
j_cmd[9] = 9, j_dat[9] = 29
In C: Step 1
c_cmd[0] = 0, c_dat[0] = 20
c_cmd[1] = 1, c_dat[1] = 21
c_cmd[2] = 2, c_dat[2] = 22
c_cmd[3] = 3, c_dat[3] = 23
c_cmd[4] = 4, c_dat[4] = 24
c_cmd[5] = 5, c_dat[5] = 25
c_cmd[6] = 6, c_dat[6] = 26
c_cmd[7] = 7, c_dat[7] = 27
c_cmd[8] = 8, c_dat[8] = 28
c_cmd[9] = 9, c_dat[9] = 29
In C: Step 2
c_cmd[0] = 10, c_dat[0] = 20
c_cmd[1] = 11, c_dat[1] = 19
c_cmd[2] = 12, c_dat[2] = 18
c_cmd[3] = 13, c_dat[3] = 17
c_cmd[4] = 14, c_dat[4] = 16
c_cmd[5] = 15, c_dat[5] = 15
c_cmd[6] = 16, c_dat[6] = 14
c_cmd[7] = 17, c_dat[7] = 13
c_cmd[8] = 18, c_dat[8] = 12
c_cmd[9] = 19, c_dat[9] = 11
In C: Step 3
size of int = 4, size of long long int = 8
0xc000050 = inl(0x0)
0x111b7000 = inl(0x0)
In C: Step 4
Java side: after Native Call
j_cmd[0] = 10, j_dat[0] = 20
j_cmd[1] = 11, j_dat[1] = 19
j_cmd[2] = 12, j_dat[2] = 18
j_cmd[3] = 13, j_dat[3] = 17
j_cmd[4] = 14, j_dat[4] = 16
j_cmd[5] = 15, j_dat[5] = 15
j_cmd[6] = 16, j_dat[6] = 14
j_cmd[7] = 17, j_dat[7] = 13
j_cmd[8] = 18, j_dat[8] = 12
j_cmd[9] = 19, j_dat[9] = 11
[root@onlsbc1 CmdData]#
---xxxx