Android 串口编程原理和实现方式附源码.docx

上传人:b****5 文档编号:5930626 上传时间:2023-01-02 格式:DOCX 页数:21 大小:60.94KB
下载 相关 举报
Android 串口编程原理和实现方式附源码.docx_第1页
第1页 / 共21页
Android 串口编程原理和实现方式附源码.docx_第2页
第2页 / 共21页
Android 串口编程原理和实现方式附源码.docx_第3页
第3页 / 共21页
Android 串口编程原理和实现方式附源码.docx_第4页
第4页 / 共21页
Android 串口编程原理和实现方式附源码.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

Android 串口编程原理和实现方式附源码.docx

《Android 串口编程原理和实现方式附源码.docx》由会员分享,可在线阅读,更多相关《Android 串口编程原理和实现方式附源码.docx(21页珍藏版)》请在冰豆网上搜索。

Android 串口编程原理和实现方式附源码.docx

Android串口编程原理和实现方式附源码

 提到串口编程,就不得不提到JNI,不得不提到JavaAPI中的文件描述符类:

FileDescriptor。

下面我分别对JNI、FileDescriptor以及串口的一些知识点和实现的源码进行分析说明。

这里主要是参考了开源项目android-serialport-api。

  串口编程需要了解的基本知识点:

对于串口编程,我们只需对串口进行一系列的设置,然后打开串口,这些操作我们可以参考串口调试助手的源码进行学习。

在Java中如果要实现串口的读写功能只需操作文件设备类:

FileDescriptor即可,其他的事都由驱动来完成不用多管!

当然,你想了解,那就得看驱动代码了。

这里并不打算对驱动进行说明,只初略阐述应用层的实现方式。

 

(一)JNI:

  关于JNI的文章网上有很多,不再多做解释,想详细了解的朋友可以查看云中漫步的技术文章,写得很好,分析也很全面,那么在这篇拙文中我强调3点:

  1、如何将编译好的SO文件打包到APK中?

(方法很简单,直接在工程目录下新建文件夹libs/armeabi,将SO文件Copy到此目录即可)

  2、命名要注意的地方?

(在编译好的SO文件中,将文件重命名为:

libfilename.so即可。

其中filename.so是编译好后生成的文件)

  3、MakeFile文件的编写(不用多说,可以直接参考package/apps目录下用到JNI的相关项目写法)

  这是关键的代码:

[cpp] viewplaincopy

1.

18px;">        int fd;  

2.        speed_t speed;  

3.        jobject mFileDescriptor;  

4.  

5.        /* Check arguments */  

6.        {  

7.                speed = getBaudrate(baudrate);  

8.                if (speed == -1) {  

9.                        /* TODO:

 throw an exception */  

10.                        LOGE("Invalid baudrate");  

11.                        return NULL;  

12.                }  

13.        }  

14.  

15.        /* Opening device */  

16.        {  

17.                jboolean iscopy;  

18.                const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);  

19.                LOGD("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);  

20.                fd = open(path_utf, O_RDWR | flags);  

21.                LOGD("open() fd = %d", fd);  

22.                (*env)->ReleaseStringUTFChars(env, path, path_utf);  

23.                if (fd == -1)  

24.                {  

25.                        /* Throw an exception */  

26.                        LOGE("Cannot open port");  

27.                        /* TODO:

 throw an exception */  

28.                        return NULL;  

29.                }  

30.        }  

31.  

32.        /* Configure device */  

33.        {  

34.                struct termios cfg;  

35.                LOGD("Configuring serial port");  

36.                if (tcgetattr(fd, &cfg))  

37.                {  

38.                        LOGE("tcgetattr() failed");  

39.                        close(fd);  

40.                        /* TODO:

 throw an exception */  

41.                        return NULL;  

42.                }  

43.  

44.                cfmakeraw(&cfg);  

45.                cfsetispeed(&cfg, speed);  

46.                cfsetospeed(&cfg, speed);  

47.  

48.                if (tcsetattr(fd, TCSANOW, &cfg))  

49.                {  

50.                        LOGE("tcsetattr() failed");  

51.                        close(fd);  

52.                        /* TODO:

 throw an exception */  

53.                        return NULL;  

54.                }  

55.        }  

56.  

(二)FileDescritor:

  文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。

文件描述符的主要实际用途是创建一个包含该结构的FileInputStream 或FileOutputStream。

这是API的描述,不太好理解,其实可简单的理解为:

FileDescritor就是对一个文件进行读写。

(三)实现串口通信细节

1) 建工程:

SerialDemo包名:

org.winplus.serial,并在工程目录下新建jni和libs两个文件夹和一个org.winplus.serial.utils,如下图:

2)新建一个类:

SerialPortFinder,添加如下代码:

[java] viewplaincopy

1.

18px;">package org.winplus.serial.utils;  

2.  

3.import java.io.File;  

4.import java.io.FileReader;  

5.import java.io.IOException;  

6.import java.io.LineNumberReader;  

7.import java.util.Iterator;  

8.import java.util.Vector;  

9.  

10.import android.util.Log;  

11.  

12.public class SerialPortFinder {  

13.  

14.    private static final String TAG = "SerialPort";  

15.  

16.    private Vector mDrivers = null;  

17.  

18.    public class Driver {  

19.        public Driver(String name, String root) {  

20.            mDriverName = name;  

21.            mDeviceRoot = root;  

22.        }  

23.  

24.        private String mDriverName;  

25.        private String mDeviceRoot;  

26.        Vector mDevices = null;  

27.  

28.        public Vector getDevices() {  

29.            if (mDevices == null) {  

30.                mDevices = new Vector();  

31.                File dev = new File("/dev");  

32.                File[] files = dev.listFiles();  

33.                int i;  

34.                for (i = 0; i < files.length; i++) {  

35.                    if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {  

36.                        Log.d(TAG, "Found new device:

 " + files[i]);  

37.                        mDevices.add(files[i]);  

38.                    }  

39.                }  

40.            }  

41.            return mDevices;  

42.        }  

43.  

44.        public String getName() {  

45.            return mDriverName;  

46.        }  

47.    }  

48.  

49.    Vector getDrivers() throws IOException {  

50.        if (mDrivers == null) {  

51.            mDrivers = new Vector();  

52.            LineNumberReader r = new LineNumberReader(new FileReader(  

53.                    "/proc/tty/drivers"));  

54.            String l;  

55.            while ((l = r.readLine()) !

= null) {  

56.                // Issue 3:

  

57.                // Since driver name may contain spaces, we do not extract  

58.                // driver name with split()  

59.                String drivername = l.substring(0, 0x15).trim();  

60.                String[] w = l.split(" +");  

61.                if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) {  

62.                    Log.d(TAG, "Found new driver " + drivername + " on "  

63.                            + w[w.length - 4]);  

64.                    mDrivers.add(new Driver(drivername, w[w.length - 4]));  

65.                }  

66.            }  

67.            r.close();  

68.        }  

69.        return mDrivers;  

70.    }  

71.  

72.    public String[] getAllDevices() {  

73.        Vector devices = new Vector();  

74.        // Parse each driver  

75.        Iterator itdriv;  

76.        try {  

77.            itdriv = getDrivers().iterator();  

78.            while (itdriv.hasNext()) {  

79.                Driver driver = itdriv.next();  

80.                Iterator itdev = driver.getDevices().iterator();  

81.                while (itdev.hasNext()) {  

82.                    String device = itdev.next().getName();  

83.                    String value = String.format("%s (%s)", device,  

84.                            driver.getName());  

85.                    devices.add(value);  

86.                }  

87.            }  

88.        } catch (IOException e) {  

89.            e.printStackTrace();  

90.        }  

91.        return devices.toArray(new String[devices.size()]);  

92.    }  

93.  

94.    public String[] getAllDevicesPath() {  

95.        Vector devices = new Vector();  

96.        // Parse each driver  

97.        Iterator itdriv;  

98.        try {  

99.            itdriv = getDrivers().iterator();  

100.            while (itdriv.hasNext()) {  

101.                Driver driver = itdriv.next();  

102.                Iterator itdev = driver.getDevices().iterator();  

103.                while (itdev.hasNext()) {  

104.                    String device = itdev.next().getAbsolutePath();  

105.                    devices.add(device);  

106.                }  

107.            }  

108.        } catch (IOException e) {  

109.            e.printStackTrace();  

110.        }  

111.        return devices.toArray(new String[devices.size()]);  

112.    }  

113.}  

114.  

上面这个类在“android-serialport-api串口工具测试随笔”中有详细的说明,我就不多说了。

3)新建SerialPort类,这个类主要用来加载SO文件,通过JNI的方式打开关闭串口

[java] viewplaincopy

1.

18px;">package org.winplus.serial.utils;  

2.  

3.import java.io.File;  

4.import java.io.FileDescriptor;  

5.import java.io.FileInputStream;  

6.import java.io.FileOutputStream;  

7.import java.io.IOException;  

8.import java.io.InputStream;  

9.import java.io.OutputStream;  

10.  

11.import android.util.Log;  

12.  

13.public class SerialPort {  

14.    private static final String TAG = "SerialPort";  

15.  

16.    /* 

17.     * Do not remove or rename the field mFd:

 it is used by native method 

18.     * close(); 

19.     */  

20.    private FileDescriptor mFd;  

21.    private FileInputStream mFileInputStream;  

22.    private FileOutputStream mFileOutputStream;  

23.  

24.    public SerialPort(File device, int baudrate, int flags)  

25.            throws SecurityException, IOException {  

26.  

27.        /* Check access permission */  

28.        if (!

device.canRead() || !

device.canWrite()) {  

29.            try {  

30.                /* Missing read/write permission, trying to chmod the file */  

31.                Process su;  

32.                su = Runtime.getRuntime().exec("/system/bin/su");  

33.                String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"  

34.                        + "exit\n";  

35.                su.getOutputStream().write(cmd.getBytes());  

36.                if ((su.waitFor() !

= 0) || !

device.canRead()  

37.                        || !

device.canWrite()) {  

38.                    throw new SecurityException();  

39.                }  

40.            } catch (Exception e) {  

41.                e.printStackTrace();  

42.                throw new SecurityException();  

43.            }  

44.        }  

45.  

46.        mFd = open(device.getAbsolutePath(), baudrate, flags);  

47.        if (mFd == null) {  

48.            Log.e(TAG, "native open returns null");  

49.            throw new IOException(

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1