我正在使用JNA库在BeagleBone上调用本机C,以便与I2C总线进行通信。与I2C总线的通信需要低级文件操作,例如open,ioctl,close,read和write。我能够打开总线文件没问题,但我无法让ioctl工作。如果我能够实现这一点,我相信我会在BeagleBone Black或Raspberry Pi上运行I2C功能。这是我的代码
import java.util.Arrays;
import java.util.List;
import com.sun.jna。*;
public class Main {
static Linux_C_lib_DirectMapping libC = new Linux_C_lib_DirectMapping();
public static int O_RDWR = 0x00000002;
public static void main(String[] args) {
new Main();
}
public Main(){
System.setProperty("jna.library.path","/usr/lib/cgi-bin/jna");
//Open I2C Bus 1 file
String fileName = "/dev/i2c-1";
int file = libC.open(fileName, O_RDWR);
if(file<0){
System.out.println("Error opening file");
return;
}else{
System.out.println("File open for reading and writing");
}
//Print out returned value from file open
System.out.println(file);
//initiate connection to chip. I2C chip I am using mounts on 0x21
int[] address = {33};
int i2c_slave = 1795;
//This is what fails. I always get -1 back.
int iocntl = libC.ioctl(file, i2c_slave, address);
//Print returned value after ioctl action
System.out.println("fcntl = "+iocntl);
if(iocntl<0){
System.out.println("error on libC.ioctl");
libC.close(file);
return;
}else{
System.out.println("ioctl complete");
}
//Initialize communication to chip
byte[] buf = {0,0};
if(libC.write(file, buf, 2) != 2){
System.out.println("error writing");
libC.close(file);
return;
}else{
System.out.println("I2C chip initialized");
}
while(true){
if(turnOnAllRelays(file)){
try {
Thread.sleep(1000);
turnOffAllRelays(file);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public boolean turnOnAllRelays(int file){
byte[] buffer = {0xA,0xF};
if(libC.write(file, buffer, 2) != 2){
System.out.println("all relays on");
return true;
}else{
System.out.println("failed to turn all relays on");
libC.close(file);
return false;
}
}
public boolean turnOffAllRelays(int file){
byte[] buffer = {0xA, 0x0};
if(libC.write(file, buffer, 2) != 2){
System.out.println("all relays off");
return true;
}else{
System.out.println("failed to turn all relays off");
libC.close(file);
return false;
}
}
public interface Linux_C_lib extends com.sun.jna.Library {
public long memcpy(int[] dst, short[] src, long n);
public int memcpy(int[] dst, short[] src, int n);
public int pipe(int[] fds);
public int tcdrain(int fd);
public int fcntl(int fd, int cmd, int arg);
public int ioctl(int fd, int cmd, int[] arg);
public int open(String path, int flags);
public int close(int fd);
public int write(int fd, byte[] buffer, int count);
public int read(int fd, byte[] buffer, int count);
public long write(int fd, byte[] buffer, long count);
public long read(int fd, byte[] buffer, long count);
public int select(int n, int[] read, int[] write, int[] error, timeval timeout);
public int poll(int[] fds, int nfds, int timeout);
public int tcflush(int fd, int qs);
public void perror(String msg);
public int tcsendbreak(int fd, int duration);
static public class timeval extends Structure {
public NativeLong tv_sec;
public NativeLong tv_usec;
@Override
protected List getFieldOrder() {
return Arrays.asList(//
"tv_sec",//
"tv_usec"//
);
}
public timeval(jtermios.TimeVal timeout) {
tv_sec = new NativeLong(timeout.tv_sec);
tv_usec = new NativeLong(timeout.tv_usec);
}
}
}
public static class Linux_C_lib_DirectMapping implements Linux_C_lib {
native public long memcpy(int[] dst, short[] src, long n);
native public int memcpy(int[] dst, short[] src, int n);
native public int pipe(int[] fds);
native public int tcdrain(int fd);
native public int fcntl(int fd, int cmd, int arg);
native public int ioctl(int fd, int cmd, int[] arg);
native public int open(String path, int flags);
native public int close(int fd);
native public int write(int fd, byte[] buffer, int count);
native public int read(int fd, byte[] buffer, int count);
native public long write(int fd, byte[] buffer, long count);
native public long read(int fd, byte[] buffer, long count);
native public int select(int n, int[] read, int[] write, int[] error, timeval timeout);
native public int poll(int[] fds, int nfds, int timeout);
native public int tcflush(int fd, int qs);
native public void perror(String msg);
native public int tcsendbreak(int fd, int duration);
static {
try {
Native.register("c");
System.out.println("registered to c library");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
调用ioctl我总是回来-1。我不熟悉这个函数,因为我没有做太多的C编程,但是相应来自Linux的示例代码,这意味着函数失败了: http://elinux.org/Interfacing_with_I2C_Devices
我应该注意到,我有想法使用JNA来完成purjavacomm的开发人员,他们似乎成功地使用了它。
任何人对我出错的地方都有任何想法?