Linux系统下使用Java访问PCI系列板卡
2021-11-18 16:40:34 来源:华启智能
本文主要介绍在Linux系统(包括国产的中标麒麟跟银河麒麟系统)下使用Java访问KCPI-1847测控板卡,也适用于操作KPCI-1840、KPCIE-1847和KPCIE-1840等PCI/PCIE系列测控板卡。
1. 使用的系统环境
本文使用Ubuntu 20.04 LTS版本Linux系统为测试环境。使用到的硬件外部硬件是KPCI-1847和KPIC-1840测控板卡和DB37端子板。Linux系统下Java开发环境使用OpenJDK 1.8和Oracle JDK1.8两个版本,使用NetBeans IDE开发,编译so动态库使用到的工具主要有gcc和make,版本如下所示:
2. 安装编译成功的驱动程序文件ch36x.ko
执行sudo insmod /home/ubuntu/CH36X_LINUX/drv/ch36x.ko 安装驱动
ubuntu@LK:~/CH36X_LINUX/drv$ sudo insmod /home/ubuntu/CH36X_LINUX/drv/ch36x.ko
执行 lsmod
ubuntu@LK:~/CH36X_LINUX/drv$ lsmod
Module Size Used by
ch36x 28672 0
代表CH365/CH367的驱动安装成功。
3. 编译操作PCI测控板卡so动态库
cd /home/ubuntu/CH36X_LINUX/lib/
gcc -c -fPIC ch36x_lib.c
生成.a文件:
ar -cr ch36x_lib.a ch36x_lib.o
生成so文件:
gcc -shared -fPIC -o ch36x_lib.so ch36x_lib.o
4. Java访问PCI测控板卡测试程序:
public interface PCI extends Library{
public int CH36xOpenDevice(byte index,int iEnableInterrupt);
public int CH36xCloseDevice();
public int CH36xGetDrvVer(byte[] drv_version);//长度不超过30
public int CH36xGetLibVer(byte[] lib_version);
public int CH36xGetIoBaseAddr(PointerByReference oIoBaseAddr);//256字节
public int CH36xSetIoBaseAddr(Pointer iIoBaseAddr);
public int CH36xGetMemBaseAddr(Pointer oMemBaseAddr);//32768字节
public int CH36xSetMemBaseAddr(Pointer iMemBaseAddr);
public int CH36xGetIntLine(IntByReference oIntLine);
public int CH36xSetIntLine(int iIntLine);
public int CH36xReadIoByte(Pointer iAddr,ByteByReference oByte);
public int CH36xReadIoWord(Pointer iAddr,ShortByReference oByte);
public int CH36xReadIoDword(Pointer iAddr,IntByReference oByte);
public int CH36xReadIoBlock(Pointer iAddr,byte[] buf,int length);
public int CH36xWriteIoByte(Pointer iAddr,byte iByte);
public int CH36xWriteIoWord(Pointer iAddr,short iByte);
public int CH36xWriteIoDword(Pointer iAddr,int iByte);
public int CH36xWriteIoBlock(Pointer iAddr,byte[] buf,int length);
public int CH36xReadMemByte(Pointer iAddr,ByteByReference oByte);
public int CH36xReadMemWord(Pointer iAddr,ShortByReference oByte);
public int CH36xReadMemDword(Pointer iAddr,IntByReference oByte);
public int CH36xReadMemBlock(Pointer iAddr,byte[] buf,int length);
public int CH36xWriteMemByte(Pointer iAddr,byte iByte);
public int CH36xWriteMemWord(Pointer iAddr,short iByte);
public int CH36xWriteMemDword(Pointer iAddr,int iByte);
public int CH36xWriteMemBlock(Pointer iAddr,byte[] buf, int length);
public int CH36xReadConfig(Pointer iAddr,ByteByReference oByte);
public int CH36xReadConfigWord(Pointer iAddr,ShortByReference oByte);
public int CH36xReadConfigDword(Pointer iAddr,IntByReference oByte);
public int CH36xWriteConfig(Pointer iAddr,byte iByte);
public int CH36xWriteConfigWord(Pointer iAddr,short iByte);
public int CH36xWriteConfigDword(Pointer iAddr,int iByte);
public int CH36xWaitInterrupt();
public int CH36xAbortInterrupt();
public int CH36xSetIntRoutine(//Setting handler for interrupter
Callback iIntRoutine);
}
NetBeans工程项目截图
Java访问KPCI-1847测控板卡程序界面
Java访问KPCIE-1840测控板卡程序界面
5. 总结
本文完成了在Linux系统下使用Java语言编写程序访问PCI系列测控板卡的目的,用的主要有使用JNA在Linux系统下调用so动态库文件,使用gcc编译和生成so动态库文件。按照PCI测控板卡说明读写相应寄存器实现完全访问PCI板卡,采集输入开关量的状态和控制输出开关量的状态。在程序调试过程中遇到过JVM异常退出的情况。
6. 参考资料
Linux下gcc编译生成动态链接库*.so文件并调用它
https://www.cnblogs.com/swordenchanter/articles/11490652.html
gcc生成.a静态库和.so动态库文件
http://blog.chinaunix.net/uid-20564848-id-73829.html