在6818平台上面的机器人开发要使用到串口资源和其他子系统的通信,虽然方案公司已经提供了一个基于Google serial-port的demo,但是只有一个简单应用,并没有源码可以使用,当然也就不能够修改及调用了,所以说根本没用。于是只有自己动手将这个串口部分的jni调试并合并到自己的系统应用里面。这个过程当中遇到很多困难,虽然网络上面已经有好多使用Google-serial-port来做自己项目的案例,但是,你不自己动手折腾一番而妄想直接copy,那么遇到的问题和花费的时间总是比自己动手要多得多。
首先把自己上传的Google serial port 示例贴上,方便大家下载参考:Google-serial-port。
我的应用都是在Google studio 上面开发然后加入到Ubuntu工作空间编译的,刚刚开始使用studio免不了又要折腾一番的,这里就不在多说。Google样例当中主要的是这三个部分:
1、jni文件夹下的:android.mk,serialport.c以及serialport.h:提供编译配置以及jni的c实现;
2、libs文件夹下面的三个子文件夹里面的.so文件:编译生成的包括arm平台的动态链接库文件;
3、src目录下面的serialport.java 和 serialportfinder.java 这两个代码文件:两个主要的串口搜索和jni方法调用的文件。
好了,这就是我的大体理解,其他的界面包括layout,xml里面的preference等这些都是小问题,一看便知。这里要提醒大家,如果你直接使用这个样例(没有修改包名等),那么将jni和libs文件夹放到你的工程,再根据两个主要的Java类来修改对应代码实现串口调用的话是比较容易实现的。但是如果你是将这个作为自己工程里面的一个功能单元,就是说包名不一样了,那么so文件也就没有用了,你必须自己动手完成so文件的生成。那么这里就要配置studio下面的你打开环境了,具体的配置方法和so的生成我是参考这个文章:http://blog.csdn.net/zhaoqi2617/article/details/53215359。在完成这个步骤后你就能够得到对应你自己工程包名的so动态库了(其实这个地方我还有个疑问,Google的demo里面包名和serial port.c里面的方法名是不一样的:
Java_android_1serialport_1api_SerialPort_open
但是为什么能够调用呢?么有搞懂~~~)。
顺利的完成了这些,那么你离成功使用串口已经很近了,接下里我大致说下遇到的问题,在我将.mk文件以及其他这些东西放到我的Ubuntu工作空间编译后,都一切正常,刷机也进入了自己的系统应用,但是进入串口就有我问题了,首先提示了:
Please configure your serial port first
这个提示来自sample下面的serialportactivity.java文件:
try {
mSerialPort = mApplication.getSerialPort();
mOutputStream = mSerialPort.getOutputStream();
mInputStream = mSerialPort.getInputStream();
/* Create a receiving thread */
mReadThread = new ReadThread();
mReadThread.start();
} catch (SecurityException e) {
DisplayError(R.string.error_security);
} catch (IOException e) {
DisplayError(R.string.error_unknown);
} catch (InvalidParameterException e) {
DisplayError(R.string.error_configuration);
}
public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException
~~~
if ( (path.length() == 0) || (baudrate == -1)) {
throw new InvalidParameterException();
}
~~
那看来是在preference里面选择的串口号或者波特率根本就没有记录到共享文件里面了!这个问题没有想明白,但是至少知道问题出在哪里了吧,反正系统里面要使用的串口就是那几个已知的,所以我直接在application.java里面指定了要使用的串口好和波特率 115200。再次经过修改和编译都OK,一切顺利,然后刷机看看效果怎么样。虽然没有提示异常了,但是他直接挂了~~~。
这就是我遇到的第二个状况了,这个问题也让我花费掉了两天的时间去排查,把所有可能的情况都分析了,把代码简化到只有so文件出问题的情况,因为在studio的ndk下生成的so是有用的,安装在自己手机上面完全可以(除了几个串口拿不到权限外,其他都正常,串口权限是我遇到的第三个问题~)。那么只有这个原因了:在Ubuntu下面编译生成的so文件不可用!我按照这个想法去解决:通过adb shell 进入到system/lib下面查看so文件:
:/system/lib # ls libserial_port.so
是有对应so文件的,我将studio下面的libserial_port.so文件push到system/lib下面覆盖原来的so文件看看~~~。果然不出所料,就是这个原因导致了应用在调用本地方法native的时候就挂掉了(为什么系统编译的so文件有问题我没有再追究)。
现在问题已经解决,通过jni能够顺利获得串口使用,测试了uart0的发送和接收数据没有问题。
但是我在使用其他串口的时候都是报没有权限使用对应的串口,因为在之前搜索问题的时候已经注意到这个权限问题,并且也有网友提出了一些解决办法,别人遇到的问题我肯定也会遇到嘛,果然也就遇到了。但是我通过这些方法都没有解决这个权限的问题,在这里将这些方法罗列出来:
1、这位其实已经将三种方式都总结了,但是对于第一种简单常用的他就没有怎么提。(http://blog.csdn.net/yiyaaixuexi/article/details/6803593)
2、这位将init.rc下面的具体修改表述了,但是我通过这样的方式并没有获取到串口权限。(http://blog.csdn.net/zhaoqi2617/article/details/53392495)
3、其他:http://www.cnblogs.com/vir56k/archive/2014/09/19/3981873.html,http://blog.csdn.net/u013686019/article/details/47981249
以上,就是我在使用串口时候遇到的问题和最后的解决方法,当然还有遗留了一些没有解决的问题,希望这些东西能够帮助到后续使用串口的开发者。如果后面有解决了这些遗留的问题,我会第一时间更新文章。