Jan 31, 2003

          onlsbc1, Red Hat Linux 8.0 のシステムでのJNIの実行
                 ---  ネイティブコードでのcamac読み出し #1
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  (http://www-online.kek.jp/~inoue/para-CAMAC/
                                   Work/CAMAC-JNI1.html)



                        高エネルギー加速器研究機構
                            素粒子原子核研究所
                         物理、オンライングループ
                                井上 栄二



	目的

	    SBC、PCM-9370にインストールしてある Red Hat Linux 8.0 のシステム上で
	  JNIを使ってCAMACを読み出す。 SBC は CAMACコントローラの中に装着して
	  ある。 ホスト名は onlsbc1 である。


	(1). 構成
	(2). ネイティブコードでCAMACを読み書きする
	(3). 新しいPCI ROM によるテスト

  --------------------------------------------------------------------


 (1). 構成

	テストに使用するマシンは onlsbc1 である。 このマシンはアドバンテク社の
	SBC、PCM-9370である。 動作している OSはRed Hat Linux 8.0 で、コンパクト
	フラッシュ上に構成してある。 Javaのバージョンは1.4.1_01 である。

	ネイティブコードはリードデータをJavaメソッドに返す。
	受け渡しは array を使用する。
	
	並列CAMACでは64ビット長のコマンドをコントローラに渡す、コントローラは
	64ビット長のリプライを返す。 しかし、SBCからPCIへのインターフェース部は
	32ビット長なので、扱うデータサイズは32ビット長とする。


 (2). ネイティブコードでCAMACを読み書きする

	SBC を装着した CAMACコントローラを使って、CAMACを読み書きする。 読み書
	きを行うモジュールは 24ビットSWレジスタである。

   (2-1). Javaのチェック

[inoue@onlsbc1 10readwrite]$ 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 10readwrite]$


   (2-2).  実行環境

[inoue@onlsbc1 10readwrite]$ env
MANPATH=:/usr/java/man
HOSTNAME=onlsbc1.kek.jp
TERM=vt100
SHELL=/bin/bash
JLESSCHARSET=japanese
HISTSIZE=1000
SSH_CLIENT=130.87.153.9 34339 22
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:
MAIL=/var/spool/mail/inoue
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/java/bin:/home/inoue/bin
INPUTRC=/etc/inputrc
PWD=/home/inoue/inoue/JNI/CAMAC/10readwrite
LANG=ja_JP.eucJP
SHLVL=1
HOME=/home/inoue
LOGNAME=inoue
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
OLDPWD=/home/inoue/inoue/JNI/CAMAC
[inoue@onlsbc1 10readwrite]$


   (2-3).  Javaコードを書く ---  array を使ってネイティブコードと値を受け渡す

[inoue@onlsbc1 test1]$ pwd
/home/inoue/inoue/JNI/CAMAC/10readwrite/test1
[inoue@onlsbc1 test1]$ ls -l
合計 20
-rw-rw-r--    1 inoue    inoue         316  1月 27 09:49 Makefile
-rw-rw-r--    1 inoue    inoue        4657  1月 27 14:24 camac.c
-rw-rw-r--    1 inoue    inoue        2135  1月 27 14:19 camac.java
drwxrwxr-x    2 inoue    inoue        4096  1月 27 13:27 int2hex
[inoue@onlsbc1 test1]$ 
[inoue@onlsbc1 test1]$ 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[]) {
    long lj_cmd;

    camac p = new camac();
//    int j_cmd[] = new int [10];
//    int j_dat[] = new int [10];
    int j_cmd[] = new int [11];
    int j_dat[] = new int [11];
    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]);
       System.out.println("   j_cmd[" + i + "] = " + Integer.toHexString(j_cmd[i
]) + ", j_dat[" + i + "] = " + j_dat[i]);

//    lj_cmd = (long) j_cmd[4] &0x7fffffff;
//    System.out.println("   long lj_cmd = " + lj_cmd);
//    lj_cmd = (char)Integer.parseInt("0C",16);
//    System.out.println("(char)Integer.parseInt() test" + (char)Integer.parseIn
t("0C",16));
//    System.out.println("   long lj_cmd = " + lj_cmd);

//    System.out.println("   j_cmd[4](hex) = " + Integer.toHexString(j_cmd[4]));
    int i = 10;
    System.out.println("   j_cmd[" + i + "] = " + Integer.toHexString(j_cmd[i])
+ ", j_dat[" + i + "] = " + Integer.toHexString(j_dat[i]));
  }
  static {
    System.loadLibrary("MyImpOfcamac");
  }
}
[inoue@onlsbc1 test1]$


   (2-4).  ネイティブコードを書く

[inoue@onlsbc1 test1]$ 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         |
// +---------+-------+-------+-------+-------+---------------------------+
*/

/* rw.c */
#include    
/* rw.c end */

#include    
#include    
#include    "camac.h"

/* add */
    unsigned long long int value;
    unsigned int camac;
/* add end */

/* rw.c */
#define BASE 0xE800
#define TX_DATA1REG BASE
#define TX_DATA2REG (BASE+4)
#define TX_STATUSREG (BASE+0x10)
#define TXSTATUS_BUSY 0x10000
#define TXSTATUS_TIMEOUT 0x20000
#define RX_DATA1REG (BASE+0x20)
#define RX_DATA2REG (BASE+0x24)
#define RX_FIFOREG  (BASE+0x30)
/*
#define CMD_F16_A0_N4 0xE0040010
#define CMD_F0_A0_N4 0xE0040000
*/
#define CMD_F16_A0_N3 0xE0030010
#define CMD_F0_A0_N3 0xE0030000
/* rw.c 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);

/* rw.c */
  int loop = 10;
/*  int i, ii, j, data, cmd, value; */
  int ii, j, data, cmd, value;

  printf("loop=%d\n", loop);
/* rw.c end */


   printf("In C: Step 1\n");
   for (i=0; i> 24;
    } while( value < 2 );

/*
  camacからの受信用レジスタを読んで camacからの応答を得る
*/
    data = inl(RX_DATA1REG);
    cmd = inl(RX_DATA2REG);
    printf("camac write command reply:  cmd = %x : data = %x\n", cmd, data);

/*
  送信可能状態になるまで待つ
*/
    value = inl(TX_STATUSREG);
    while (value & TXSTATUS_BUSY) {
      if (value & TXSTATUS_TIMEOUT) break;
      value = inl(TX_STATUSREG);
    }

/*
  camac readコマンド&データをセットして、PCIレジスタに書き込む
*/
/*    outl(CMD_F0_A0_N4, TX_DATA2REG); */
    outl(CMD_F0_A0_N3, TX_DATA2REG);

/*
  camac応答が読み出し可能状態になるまで待つ
*/
    value = 0;
    do {
      value = inl(RX_FIFOREG);
      value = value >> 24;
    } while( value < 2);

/*
  camacからの受信用レジスタを読んで camacからの応答を得る
*/
    data = inl(RX_DATA1REG);
    cmd = inl(RX_DATA2REG);
    data = 0xffffff & data;
    ii = 0xffffff & i;
//    printf("cmd = %x : data = %x\n", cmd, data);
    printf("camac read command reply:  cmd = %x : data = %x\n", cmd, data);
    if( data != ii ) {
      printf( "written data = %x : read data = %x\n", ii, data);
      exit(0);
    }
/* E.Inoue
    cmd = 0xffffffff & cmd;
 end */
    c_cmd[i] = cmd;
    c_dat[i] = data;
  }

/*  printf("i = %d\n", i); */
  c_cmd[i] = 0xffffffff;
  c_dat[i] = 0xffffffff;

/* rw.c 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 test1]$


   (2-5).  コードをコンパイルする

[inoue@onlsbc1 test1]$ cat Makefile

all : camac.class camac.h libMyImpOfcamac.so

camac.class:    camac.java
        javac camac.java

camac.h:        camac.class
        javah -jni camac

libMyImpOfcamac.so:     camac.c
        gcc -O -shared -I/usr/java/include -I/usr/java/include/linux camac.c -o
libMyImpOfcamac.so

clean:
        rm -f camac.class camac.h libMyImpOfcamac.so *.o core *~
[inoue@onlsbc1 test1]$
[inoue@onlsbc1 test1]$ make clean
rm -f camac.class camac.h libMyImpOfcamac.so *.o core *~
[inoue@onlsbc1 test1]$ make
javac camac.java
javah -jni camac
gcc -O -shared -I/usr/java/include -I/usr/java/include/linux camac.c -o libMyImp
Ofcamac.so
[inoue@onlsbc1 test1]$
[inoue@onlsbc1 test1]$ ls -l
合計 36
-rw-rw-r--    1 inoue    inoue         316  1月 27 09:49 Makefile
-rw-rw-r--    1 inoue    inoue        4657  1月 27 14:24 camac.c
-rw-rw-r--    1 inoue    inoue        1276  1月 27 15:45 camac.class
-rw-rw-r--    1 inoue    inoue         384  1月 27 15:45 camac.h
-rw-rw-r--    1 inoue    inoue        2135  1月 27 14:19 camac.java
drwxrwxr-x    2 inoue    inoue        4096  1月 27 13:27 int2hex
-rwxrwxr-x    1 inoue    inoue        7456  1月 27 15:45 libMyImpOfcamac.so
[inoue@onlsbc1 test1]$


  (2-6).  実行

[root@onlsbc1 test1]# pwd
/home/inoue/inoue/JNI/CAMAC/10readwrite/test1
[root@onlsbc1 test1]# ls -l
合計 36
-rw-rw-r--    1 inoue    inoue         316  1月 27 09:49 Makefile
-rw-rw-r--    1 inoue    inoue        4657  1月 27 14:24 camac.c
-rw-rw-r--    1 inoue    inoue        1276  1月 27 15:45 camac.class
-rw-rw-r--    1 inoue    inoue         384  1月 27 15:45 camac.h
-rw-rw-r--    1 inoue    inoue        2135  1月 27 14:19 camac.java
drwxrwxr-x    2 inoue    inoue        4096  1月 27 13:27 int2hex
-rwxrwxr-x    1 inoue    inoue        7456  1月 27 15:45 libMyImpOfcamac.so
[root@onlsbc1 test1]#
[root@onlsbc1 test1]# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
[root@onlsbc1 test1]# 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
loop=10
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
      c_cmd[10] = 0, c_dat[10] = 0
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
      c_cmd[10] = 10, c_dat[10] = -20
In C: Step 3
      size of int = 4, size of long long int = 8
      0x9 = inl(0xe800)
      0xe0030000 = inl(0xe804)
camac write data:  data = 0
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 0
camac write data:  data = 1
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 1
camac write data:  data = 2
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 2
camac write data:  data = 3
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 3
camac write data:  data = 4
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 4
camac write data:  data = 5
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 5
camac write data:  data = 6
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 6
camac write data:  data = 7
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 7
camac write data:  data = 8
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 8
camac write data:  data = 9
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 9
In C: Step 4
Java side:  after Native Call
   j_cmd[0] = e0030000, j_dat[0] = 0
   j_cmd[1] = e0030000, j_dat[1] = 1
   j_cmd[2] = e0030000, j_dat[2] = 2
   j_cmd[3] = e0030000, j_dat[3] = 3
   j_cmd[4] = e0030000, j_dat[4] = 4
   j_cmd[5] = e0030000, j_dat[5] = 5
   j_cmd[6] = e0030000, j_dat[6] = 6
   j_cmd[7] = e0030000, j_dat[7] = 7
   j_cmd[8] = e0030000, j_dat[8] = 8
   j_cmd[9] = e0030000, j_dat[9] = 9
   j_cmd[10] = ffffffff, j_dat[10] = ffffffff
[root@onlsbc1 test1]#

	ok.  ネイティブコードで実行した camac read 実行で読み出したデータを
	Javaメソッドに正常に渡すことができた。


 (3). 新しいPCI ROM によるテスト

	Jan 31, 2003 ファード社から DMA write対応のPCI用の新しいROMが届いた。 
	このROMでは以下の点が変更になっている。

		TX_STATUSREG のアドレスが BASE+0x10 から BASE+0x1c へ変更。
		RX_FIFOREG   のアドレスが BASE+0x30 から BASE+0x3c へ変更。

	これを onlsbc1 が装着してある camacコントローラに挿した。 上記のアドレス
	を変更後 JNIによるcamac 読み出しソフトを実行してみる。

[inoue@onlsbc1 test2]$ pwd
/home/inoue/inoue/JNI/CAMAC/10readwrite/test2
[inoue@onlsbc1 test2]$ make
gcc -O -shared -I/usr/java/include -I/usr/java/include/linux camac.c -o libMyImp
Ofcamac.so
[inoue@onlsbc1 test2]$

[root@onlsbc1 test2]# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
[root@onlsbc1 test2]# 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
loop=10
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
      c_cmd[10] = 0, c_dat[10] = 0
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
      c_cmd[10] = 10, c_dat[10] = -20
In C: Step 3
      size of int = 4, size of long long int = 8
      0x0 = inl(0xe800)
      0xe0030010 = inl(0xe804)
camac write data:  data = 0
				<--- ここでフリーズする。 CTL-Cで停止させた。
[root@onlsbc1 test2]#

	調べたところ以下の部分でループしていた。

		:
/*
  camac応答が読み出し可能状態になるまで待つ
*/
    value = 0;
    do {
      value = inl(RX_FIFOREG);
      value = value >> 24;
    } while( value < 2);
		:

	value = inl(RX_FIFOREG); で返された値は、読み出し可能なデータの数である
	0x2 がセットされている。 24ビットシフトはしなくてもよさそうだ。
	これを外して実行してみる。

[inoue@onlsbc1 test1]$ vi 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         |
// +---------+-------+-------+-------+-------+---------------------------+
*/

/* rw.c */
#include    
/* rw.c end */

#include    
#include    
#include    "camac.h"

/* add */
    unsigned long long int value;
    unsigned int camac;
/* add end */

/* rw.c */
#define BASE 0xE800
#define TX_DATA1REG BASE
#define TX_DATA2REG (BASE+4)
/* #define TX_STATUSREG (BASE+0x10) */
#define TX_STATUSREG (BASE+0x1c)
#define TXSTATUS_BUSY 0x10000
#define TXSTATUS_TIMEOUT 0x20000
#define RX_DATA1REG (BASE+0x20)
#define RX_DATA2REG (BASE+0x24)
/* #define RX_FIFOREG  (BASE+0x30) */
#define RX_FIFOREG  (BASE+0x3c)
/*
#define CMD_F16_A0_N4 0xE0040010
#define CMD_F0_A0_N4 0xE0040000
*/
#define CMD_F16_A0_N3 0xE0030010
#define CMD_F0_A0_N3 0xE0030000
/* rw.c 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);

/* rw.c */
  int loop = 10;
/*  int i, ii, j, data, cmd, value; */
  int ii, j, data, cmd, value;

  printf("loop=%d\n", loop);
/* rw.c end */


   printf("In C: Step 1\n");
   for (i=0; i> 24;
*/
    } while( value < 2 );

/*
  camacからの受信用レジスタを読んで camacからの応答を得る
*/
    data = inl(RX_DATA1REG);
    cmd = inl(RX_DATA2REG);
    printf("camac write command reply:  cmd = %x : data = %x\n", cmd, data);

/*
  送信可能状態になるまで待つ
*/
    value = inl(TX_STATUSREG);
    while (value & TXSTATUS_BUSY) {
      if (value & TXSTATUS_TIMEOUT) break;
      value = inl(TX_STATUSREG);
    }

/*
  camac readコマンド&データをセットして、PCIレジスタに書き込む
*/
/*    outl(CMD_F0_A0_N4, TX_DATA2REG); */
    outl(CMD_F0_A0_N3, TX_DATA2REG);

/*
  camac応答が読み出し可能状態になるまで待つ
*/
    value = 0;
    do {
      value = inl(RX_FIFOREG);
/* for PCI ROM of new version
      value = value >> 24;
*/
    } while( value < 2);

/*
  camacからの受信用レジスタを読んで camacからの応答を得る
*/
    data = inl(RX_DATA1REG);
    cmd = inl(RX_DATA2REG);
    data = 0xffffff & data;
    ii = 0xffffff & i;
//    printf("cmd = %x : data = %x\n", cmd, data);
    printf("camac read command reply:  cmd = %x : data = %x\n", cmd, data);
    if( data != ii ) {
      printf( "written data = %x : read data = %x\n", ii, data);
      exit(0);
    }
/* E.Inoue
    cmd = 0xffffffff & cmd;
 end */
    c_cmd[i] = cmd;
    c_dat[i] = data;
  }

/*  printf("i = %d\n", i); */
  c_cmd[i] = 0xffffffff;
  c_dat[i] = 0xffffffff;

/* rw.c 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 test2]$

[inoue@onlsbc1 test2]$ make
gcc -O -shared -I/usr/java/include -I/usr/java/include/linux camac.c -o libMyImp
Ofcamac.so
[inoue@onlsbc1 test2]$

[root@onlsbc1 test2]# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
[root@onlsbc1 test2]# 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
loop=10
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
      c_cmd[10] = 0, c_dat[10] = 0
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
      c_cmd[10] = 10, c_dat[10] = -20
In C: Step 3
      size of int = 4, size of long long int = 8
      0x0 = inl(0xe800)
      0xe0030000 = inl(0xe804)
camac write data:  data = 0
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 0
camac write data:  data = 1
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 1
camac write data:  data = 2
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 2
camac write data:  data = 3
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 3
camac write data:  data = 4
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 4
camac write data:  data = 5
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 5
camac write data:  data = 6
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 6
camac write data:  data = 7
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 7
camac write data:  data = 8
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 8
camac write data:  data = 9
camac write command reply:  cmd = e0030010 : data = 23000000
camac read command reply:  cmd = e0030000 : data = 9
In C: Step 4
Java side:  after Native Call
   j_cmd[0] = e0030000, j_dat[0] = 0
   j_cmd[1] = e0030000, j_dat[1] = 1
   j_cmd[2] = e0030000, j_dat[2] = 2
   j_cmd[3] = e0030000, j_dat[3] = 3
   j_cmd[4] = e0030000, j_dat[4] = 4
   j_cmd[5] = e0030000, j_dat[5] = 5
   j_cmd[6] = e0030000, j_dat[6] = 6
   j_cmd[7] = e0030000, j_dat[7] = 7
   j_cmd[8] = e0030000, j_dat[8] = 8
   j_cmd[9] = e0030000, j_dat[9] = 9
   j_cmd[10] = ffffffff, j_dat[10] = ffffffff
[root@onlsbc1 test2]#

	ok.  正常に実行できた。

---xxxx