【问题标题】:Serial port programming on Android-BeagleboardAndroid-Beagleboard 上的串口编程
【发布时间】:2010-07-13 09:08:43
【问题描述】:

我正在将一个 linux 应用程序移植到 android 上,它在 beagle board 上运行。

我的应用程序必须访问串行端口(发送/接收)。 是否可以使用应用程序读取/写入串行端口,除非 android 是“root”的?

【问题讨论】:

    标签: android serial-port beagleboard


    【解决方案1】:

    查看此页面:http://code.google.com/p/android-serialport-api/

    如果我正确理解了您的问题,这应该是您要查找的内容。

    希望我有所帮助。

    【讨论】:

      【解决方案2】:

      我为 Android 编写了一个 SerialPortChannel 类。它使用JNA

      // Copyright 2015 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
      // www.source-code.biz, www.inventec.ch/chdh
      //
      // This module is multi-licensed and may be used under the terms of any of the following licenses:
      //
      //  LGPL, GNU Lesser General Public License, V2.1 or later, http://www.gnu.org/licenses/lgpl.html
      //  EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal
      //
      // Please contact the author if you need another license.
      // This module is provided "as is", without warranties of any kind.
      //
      // Home page: http://www.source-code.biz/snippets/java/SerialPortChannel
      
      package biz.source_code.utils;
      
      import java.io.FileDescriptor;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.lang.reflect.Method;
      import java.nio.ByteBuffer;
      import java.nio.channels.ByteChannel;
      import java.nio.channels.FileChannel;
      import java.util.Arrays;
      import java.util.List;
      import com.sun.jna.LastErrorException;
      import com.sun.jna.Library;
      import com.sun.jna.Native;
      import com.sun.jna.Pointer;
      import com.sun.jna.Structure;
      
      /**
      * A serial port channel for Android.
      *
      * <p>This class uses JNA to access a serial port device (TTY) of the Android operating system.
      */
      public class SerialPortChannel implements ByteChannel {
      
      private boolean            isOpen;
      private int                fileHandle;
      private FileDescriptor     fileDescriptor;
      private FileInputStream    rxStream;
      private FileOutputStream   txStream;
      private FileChannel        rxChannel;
      private FileChannel        txChannel;
      
      /**
      * Creates a serial port channel.
      *
      * @param fileName
      *   The file name of the serial port device, e.g. "/dev/ttyO2".
      * @param baudRate
      *   The baud rate for the serial port, e.g. 9600.
      * @param blocking
      *   <code>true</code> for blocking i/o or <code>false</code> for non-blocking i/o.
      */
      public SerialPortChannel (String fileName, int baudRate, boolean blocking) throws IOException {
         staticInit();
         try {
            open(fileName, baudRate, blocking); }
          finally {
            if (!isOpen) {
               close2(); }}}
      
      private void open (String fileName, int baudRate, boolean blocking) throws IOException {
         int mode = LibcDefs.O_RDWR | (blocking ? 0 : LibcDefs.O_NONBLOCK);
         fileHandle = libc.open(fileName, mode);
         fileDescriptor = createFileDescriptor(fileHandle);
         configureSerialPort(baudRate);
         rxStream = new FileInputStream(fileDescriptor);
         txStream = new FileOutputStream(fileDescriptor);
         rxChannel = rxStream.getChannel();
         txChannel = txStream.getChannel();
         isOpen = true; }
      
      private void configureSerialPort (int baudRate) throws IOException {
         termios cfg = new termios();
         LibcDefs.tcgetattr(fileHandle, cfg);
         LibcDefs.cfmakeraw(cfg);
         int baudRateCode = encodeBaudRate(baudRate);
         LibcDefs.cfsetospeed(cfg, baudRateCode);
         LibcDefs.tcsetattr(fileHandle, cfg); }
      
      @Override public boolean isOpen() {
         return isOpen; }
      
      @Override public void close() throws IOException {
         if (!isOpen) {
            return; }
         isOpen = false;
         close2(); }
      
      private void close2() throws IOException {
         if (fileHandle != 0) {
            libc.close(fileHandle); }
         if (rxStream != null) {
            rxStream.close(); }
         if (txStream != null) {
            txStream.close(); }}
      
      @Override public int read (ByteBuffer buf) throws IOException {
         return rxChannel.read(buf); }
      
      public int read (byte[] buf) throws IOException {
         return read(ByteBuffer.wrap(buf)); }
      
      @Override public int write (ByteBuffer buf) throws IOException {
         return txChannel.write(buf); }
      
      public int write (byte[] buf, int pos, int len) throws IOException {
         return write(ByteBuffer.wrap(buf, pos, len)); }
      
      public int write (byte[] buf) throws IOException {
         return write(buf, 0, buf.length); }
      
      private static int encodeBaudRate (int baudRate) {
         switch (baudRate) {
            case 0:       return 0000000;
            case 50:      return 0000001;
            case 75:      return 0000002;
            case 110:     return 0000003;
            case 134:     return 0000004;
            case 150:     return 0000005;
            case 200:     return 0000006;
            case 300:     return 0000007;
            case 600:     return 0000010;
            case 1200:    return 0000011;
            case 1800:    return 0000012;
            case 2400:    return 0000013;
            case 4800:    return 0000014;
            case 9600:    return 0000015;
            case 19200:   return 0000016;
            case 38400:   return 0000017;
            case 57600:   return 0010001;
            case 115200:  return 0010002;
            case 230400:  return 0010003;
            case 460800:  return 0010004;
            case 500000:  return 0010005;
            case 576000:  return 0010006;
            case 921600:  return 0010007;
            case 1000000: return 0010010;
            case 1152000: return 0010011;
            case 1500000: return 0010012;
            case 2000000: return 0010013;
            case 2500000: return 0010014;
            case 3000000: return 0010015;
            case 3500000: return 0010016;
            case 4000000: return 0010017;
            default: throw new IllegalArgumentException("Unsupported baud rate " + baudRate + "."); }}
      
      //------------------------------------------------------------------------------
      
      private static Libc     libc;
      private static Method   fileDescriptorSetInt;
      private static boolean  staticInitDone;
      
      private static interface Libc extends Library {
      
         // fcntl.h
         int open(String path, int mode) throws LastErrorException;
      
         // unistd.h
         int close(int fileHandle) throws LastErrorException;
         int ioctl(int fileHandle, int request, Pointer p) throws LastErrorException; }
      
      private static class LibcDefs {
      
         // fcntl.h
         static final int O_RDWR     = 00000002;
         static final int O_NONBLOCK = 00004000;
      
         // ioctls.h
         static final int TCGETS = 0x5401;                       // for ARM and X86, Mips is 0x540d
         static final int TCSETS = 0x5402;
      
         // termios.h
         static final int IGNBRK = 0000001;
         static final int BRKINT = 0000002;
         static final int PARMRK = 0000010;
         static final int ISTRIP = 0000040;
         static final int INLCR  = 0000100;
         static final int IGNCR  = 0000200;
         static final int ICRNL  = 0000400;
         static final int IXON   = 0002000;
         static final int OPOST  = 0000001;
         static final int ISIG   = 0000001;
         static final int ICANON = 0000002;
         static final int ECHO   = 0000010;
         static final int ECHONL = 0000100;
         static final int IEXTEN = 0100000;
         static final int CBAUD  = 0010017;
         static final int CSIZE  = 0000060;
         static final int PARENB = 0000400;
         static final int CS8    = 0000060;
         private static void tcgetattr (int fileHandle, termios cfg) throws IOException {
            if (libc.ioctl(fileHandle, TCGETS, cfg.getPointer()) != 0) {
               throw new IOException("tcgetattr failed."); }
            cfg.read(); }
         private static void tcsetattr (int fileHandle, termios cfg) throws IOException {
            cfg.write();
            if (libc.ioctl(fileHandle, TCSETS, cfg.getPointer()) != 0) {
               throw new IOException("tcsetattr failed."); }}
         private static void cfmakeraw (termios cfg) {
            cfg.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
            cfg.c_oflag &= ~OPOST;
            cfg.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
            cfg.c_cflag &= ~(CSIZE|PARENB);
            cfg.c_cflag |= CS8; }
         private static void cfsetospeed (termios cfg, int baudRateCode) {
            cfg.c_cflag = (cfg.c_cflag & ~CBAUD) | (baudRateCode & CBAUD); }}
      
      private static class termios extends Structure {
         public int c_iflag;
         public int c_oflag;
         public int c_cflag;
         public int c_lflag;
         public byte c_line;
         public byte[] c_cc = new byte[32];                      // actual length depends on platform (currently 19 for ARM and X86, 23 for Mips)
         @Override protected List<?> getFieldOrder() {
            return Arrays.asList("c_iflag", "c_oflag", "c_cflag", "c_lflag", "c_line", "c_cc"); }}
      
      private static synchronized void staticInit() {
         if (staticInitDone) {
            return; }
         libc = (Libc)Native.loadLibrary("c", Libc.class);
         try {
            fileDescriptorSetInt = FileDescriptor.class.getDeclaredMethod("setInt$", int.class); }
          catch (Exception e) {
             throw new RuntimeException(e); }
         staticInitDone = true; }
      
      // This method is Android-specific and does not work with the normal Java runtime library.
      private static FileDescriptor createFileDescriptor (int fileHandle) {
         FileDescriptor fileDescriptor = new FileDescriptor();
         try {
            fileDescriptorSetInt.invoke(fileDescriptor, fileHandle); }
          catch (Exception e) {
            throw new RuntimeException(e); }
         return fileDescriptor; }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多