家蛙树

Android串口入门

Zealot
Java
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条评论
其他心得
1.Kafka排序服务原理 官方文档在google doc上, 参考翻译 https://www.jianshu.com/p/db006359133d 2. kafka 排序服务安装 所有的代码已分享在https://github.com/zealzeng/kafka-orderer-demo 2.1 安装环境 官方文档有一些简单的描述 https://hyperledger-fabric.readthedocs.io/en/release-1.4/kafka.h
Zealot · 16天前 
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
2.3 拜占庭问题 The Byzantine Generals Problem拜占庭将军问题是Lesilie Lamport等人 1982年发表的论文, 具体PDF链接, http://lamport.azurewebsites.net/pubs/byz.pdf 拜占庭问题假设一个场景,拜占庭的多个军队围攻地方的一个城市,军队的将军通过信使交换信息,在观察敌军的情况后将军们必须达成统一的作战计划。但是将军中可能有叛徒,会阻止其它将军达成一致决定。 将军们就需要一个算法保证所有忠诚的将军达
编写过一些链码的人可能会觉得是在操作一个简单的key-value数据库, 就是GetState和PutState去操作键值对,而对复杂些的一对多,多对多等实体关系和数据模型不知怎么设计。我们先从官方的例子入手一起探讨下。 1.简单转账例子 /fabric-samples/chaincode/chaincode_example02/go/chaincode_example02.go 假设链码调用peer chaincode invoke … -c ‘{“Args”:[“invoke”,”a
Zealot · 53天前 
区块链的真实数据依赖于物联网和智能设备,记一次折腾的android无线调试经历。 Android 4.2.2定制版智能硬件, USB口能插鼠标键盘, 但是不能USB调试。供应商两个方案, 要么开壳找到USB OTG排座, USB口自己接线, 但是开壳会导致硬件功能无法使用; 要么手工打包apk安装到硬件慢慢的toast。 摸索出第三条路。 搜索android无线调试, 基本都需要第一次USB调试线, adb tcpip 5555开启android设备端口监听, 之后adb connect ip