Android串口入门

Zealot
编程语言
2019-01-31

1.Andorid串口开发包一般使用google多年前提供的android-serialport-api, 提供自用分支
https://github.com/zealzeng/android-serialport-api

2.Android设备一般需要root, 保证设备串口文件如/dev/ttyS0, /dev/ttyUSB0等可读可写, 如果无权限, 则需要切到su执行chmod 666。需要注意的是有些设备su路径是/system/bin/su, 有些是/system/xbin/su. 见SerialPort.java关键代码.

public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

   /* Check access permission */
   if (!device.canRead() || !device.canWrite()) {
      Process su = null;
      try {
         /* Missing read/write permission, trying to chmod the file */
         //su = Runtime.getRuntime().exec("/system/bin/su");
         su = Runtime.getRuntime().exec("/system/xbin/su");
         String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + "exit\n";
         su.getOutputStream().write(cmd.getBytes());
         if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) {
            throw new SecurityException();
         }
      }
      catch (Exception e) {
         e.printStackTrace();
         throw new SecurityException();
      }
      finally {
         if (su != null) {
            su.destroy();
         }
      }
   }

3.如何确定串口文件和波特率? 可以先使用android串口工具例如Com Assistant等, 一般串口文件是/dev/ttyS, /dev/ttyUSB(com转USB),波特率一般连接的硬件可设置,一般是9600, 19200, 最好咨询供应商。

4.分支自带了armeabi, armeabi-v7a, x86的libserial_port.so, 一般够用, 想玩下C的可自行build, 建议使用新些的android studio 3.3, 使用cmake比ndk make感觉方便很多, 以前c源文件找不到头文件却可编译过的bug都修复了, 追踪源码方便多了。 需要注意的是新建项目向导不再是include c++ support, 而是选择新的项目类型”Native C++”

t_72d6e4dd462940ad8175ce37e6fe6a7b.png
修改自动生成的CMakeList.txt即可

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
        serial_port

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        SerialPort.c)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        serial_port

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

5.串口读写阻塞设置
SerialPort.c

fd = open(path_utf, O_RDWR | flags);

Linux的open函数用于打开文件, flags一般我们传入0, 默认阻塞IO, 与Java的blocking IO一致。当日flags也可设置为O_NONBLOCK非阻塞, 与Java的NIO一致。

#ifndef O_NONBLOCK
#define O_NONBLOCK 00004000
#endif

一般串口的是独占的, 使用blocking IO编程会感觉简单些。

6.串口通信协议
硬件方定义通信协议, 有些是回车换行作为分隔符, 分隔符前还有奇偶校验,笔者看到一些android串口的扩展支持设置奇偶位, 数据位和停止位, 有一些疑惑。 因为默认按照一个字节一个字节流的读法, 遇到分割符才处理, 最多额外处理奇偶校验;笔者调通的硬件不多, 期待大家指教。

  switch (parity) {
            case 0: break;
            case 1: cfg.c_cflag |= PARENB; break;
            case 2: cfg.c_cflag &= ~PARODD; break;
        }
        switch (dataBits) {
            case 5: cfg.c_cflag |= CS5; break;
            case 6: cfg.c_cflag |= CS6; break;
            case 7: cfg.c_cflag |= CS7; break;
            case 8: cfg.c_cflag |= CS8; break;
        }
        switch (stopBit) {
            case 1: cfg.c_cflag &= ~CSTOPB; break;
            case 2: cfg.c_cflag |= CSTOPB; break;
}

7.串口重连
串口被拔插时应用需要支持重连,在遇到InputStream,OutputStream读取返回-1或不可能恢复的问题时, 处理串口的线程应当捕获错误, 优雅关闭当前串口资源,尝试重连,保证串口应用的健壮性。

8.Android串口消息的通知
串口通常是独占, 不能被多个android app打开, 所以很多时候android需要开一个服务, 负责监听串口消息,之后做广播到监听的app处理。

暂时用到这个度, 有问题再交流。

t_7b47206f4c044202b8552871e7995815.png

点赞 0
0条评论
其他心得
Zealot · 14天前 
去年得知蚂蚁金服放出SOFA的部分开源项目, RPC部分号称源于阿里内部的HSF, HSF当年可是把dubbo 1.x踢出局的, 只是没想到京东改造dubbo为JSF, 当当改为dubbox。国内蛮多电商公司实施服务化就直接上dubbo 1.x或dubbox。这应该是阿里没想到的, 所以现在dubbo 2.x又回笼为apache的顶级项目, 把dubbox合并还继续完善。 朋友说他们公司花了千万买了SOFA的商业版, 那么值钱的东西今天抽空过了一下开源部分的SOFAStack和dubbo2.x文档
Zealot · 23天前 
Fabric 1.4.1引入Raft排序服务, 运维界比较出名的etcd实现的orderer服务。后生可畏, etcd是中国一个年轻人的作品, 实现了raft协议, 在k8s等容器化, 虚拟化, 集群化有官方应用。etcd也是go语言编写, fabric开窍了, 直接把etcd和orderer整合了, 相比kafka/zookeeper的排序服务,搭建简单多了,也比kafka这些省了很多资源(kafka默认开的堆是2GB..), 所以个人是强烈推荐使用,尽量出来不久,但在1.4LTS维护,
Luoying web framework Luoying web framework contains a bundle of components to accelerate J2EE development Github地址 https://github.com/zealzeng/luoying-web Maven地址 <dependency> <groupId>com.whlylc</groupId> <artifac
Zealot · 31天前 
Hyperledger Fabric v2.0 Alpha引入两大新功能,新的Fabric链码生命周期和FabToken. 新的链码生命周期 2.0支持链码的去中心化的治理,引入新的流程在节点上安装链码,在通道上启动实例。新的链码生命周期允许多个组织对链码的参数协同达成一致,例如链码的背书策略。新的模型的改进点如下: (1) 多个组织必须确认同意链码的参数 1.x版本里,一个组织拥有修改链码参数的能力,例如修改背书策略,通道的其它成员也被同步而更改。新的链码生命周期更灵活一些,它兼容支
Zealot · 107天前 
1.简介 Fabric 1.4引入operation service即运维服务接口, orderer,peer节点可提供http服务, 方便外部获取节点的运行指标,管理日志级别,健康检查。 2.如何使用运维服务 以fabirc-sample/first-network为例, ./byfn.sh up 2.1 Orderer节点运维服务 启动后连接到orderer容器 docker exec -it -e LINES=$(tput lines) -e COLUMNS=$(tput co