Android串口通信
背景
- Platform: RK3399
- OS: Android7.1.2
- Kernel: v4.4.103
内核及系统配置
正常流程
RK3399的串口采用的是8250通用驱动.
- 确定DTS里面已经okey,dev下设备节点是否存在
- 确认设备节点权限:
文件(./device/rockchip/common/ueventd.rockchip.rc
):/dev/ttyS4 0666 system system
Selinux问题(未验证,开启Selinux后需注意):
- 在device/rockchip/rk3399/xxx/sepolicy/目录下,添加untrusted_app.te;
allow untrusted_app serial_device:chr_file {read open ioctl getattr create write};
- 在device.mk和system_server.te添加并编译权限;
+BOARD_SEPOLICY_DIRS += \ + device/rockchip/rk3399/rk3399_firefly_edp_box/sepolicy + +BOARD_SEPOLICY_UNION += \ + untrusted_app.te rw_dir_perms包含read write; +#untrusted_app +allow system_server serial_device:chr_file rw_file_perms;
- selinux security level引起的denied u:r:untrusted_app:s0:c512,c768问题,由于security level为MLS访问机制所添加的安全上下文的扩展部分mlstrustedsubject,这一attribute包含了所有能越过MLS检查的客体type。所以在device.te加入type serial_device, dev_type, mlstrustedobject;
2019-06-04 11:40:17.518 1696-1696/? W/ample.hello_ros: type=1400 audit(0.0:74): avc: denied { write } for name="ttyS3" dev="tmpfs" ino=2524 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:serial_device:s0 tclass=chr_f
JNI
Android并没有包含串口的JNI, 需要我们自己实现。(Android Thing已经有实现)
串口JNI的参考范例见谷歌的开源代码 android_serial_api: https://github.com/cepr/android-serialport-api
准备SO文件
使用现成的SO文件,但可能存在版本不兼容问题。
使用NDK重新编译so文件,可参考:使用NDK编译原生库或可执行应用程序
配置工程
- 在工程java目录下新建package, 名称固定为
android_serialport_api
- 将源码里的Java文件
SerialPort.java
、SerialportFinder.java
拷贝到上面新建的包下 - 新建libs目录,拷贝编译好的SO文件到该目录,根据自己的平台选择对应的APP_ABI文件夹
- 在build.grandle(Moudle:app)中添加:
android{ ... sourceSets { main() { jniLibs.srcDirs = ['libs'] } } ... }
参考
- [RK3399][Android7.1] 调试笔记 — 串口JNI测试用例
- Android 串口通讯集成
- Android 串口开发
评论