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