Using JNA for Open, Close, and ioctl functions on Ubuntu 13.0.4 running on Beagle Bone Black I2C

1,595 views
Skip to first unread message

Travis Elliott

unread,
Apr 4, 2014, 12:34:43 PM4/4/14
to jna-...@googlegroups.com
First I would just like to say thank you for the development of the JNA library.  It seems to fill a huge hole in JAVA.

I am currently trying to use the I2C port on a Beagle Bone Black(similar to Raspberry Pi).  Use requires access to native C functions including ioctl.  This is where my problem begins.  I am able to call the JNA open function but ioctl returns -1 no matter what I try.  I don't know if I am passing the wrong parameters to the function or what.  My code is based on two bits of research, the first is sample code from the purejavacomm library and the second is an article from Linux on interfacing to the I2C functions using standard C programming.  Here are links:

Also here is a link to the datasheet for the chip I am using if anyone is interested: http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf

I may be using the wrong parameters for the ioctl call but I honestly don't know.  I do not know a lot about standard C since I have mainly lived in the Java world.  I should also note this is a Linux ARM processor running Ubuntu 13.0.4  

Here is my code thus far:

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();
        }
    }
}

Timothy Wall

unread,
Apr 5, 2014, 4:32:54 PM4/5/14
to jna-...@googlegroups.com
I think you need to pass the address “0x33” directly as an integer, rather than by reference (i.e. int[]).
> --
> You received this message because you are subscribed to the Google Groups "Java Native Access" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Travis Elliott

unread,
Apr 7, 2014, 10:36:45 AM4/7/14
to jna-...@googlegroups.com
Hi Timothy,

Thank you so much.  That seems to have fixed the ioctl call.  I am now getting 0 back on that call rather than -1 when I pass an int instead of int[].  I always thought that was kind of weird.  Now that I am past that point I am having difficulty with the write command.  Can you tell me where in your library source that method is declared?  I looked through your library source but was unable to find it.

Thank you!,
Travis Elliott

Timothy Wall

unread,
Apr 7, 2014, 11:27:41 AM4/7/14
to jna-...@googlegroups.com
are you referring to “write” in the C runtime library or something else?

Travis Elliott

unread,
Apr 7, 2014, 11:00:16 PM4/7/14
to jna-...@googlegroups.com
Hi Timothy,

I just wanted to let you know I have it working and could not be more thankful for not only your great library which brings something really important to Java but also for your help on using it.  JNA is definitely a must and works great, hard to believe Oracle or Sun didn't already have this but thanks to you for making it available to the rest of the world.  I will post my code in a couple days for anyone else out there wanting to interface to I2C through Java.  

Thanks again Timothy,
Travis Elliott

Timothy Wall

unread,
Apr 8, 2014, 10:23:34 PM4/8/14
to jna-...@googlegroups.com
Glad to hear you found success,

T.
Reply all
Reply to author
Forward
0 new messages