|
|
Line 1: |
Line 1: |
− | [[Android Hardware Programming for RK3399|English]]
| + | ==函数库(libfriendlyarm-hardware.so)接口说明== |
− | | + | 在应用层,可透过上一章节中的HardwareControler类来调用libfriendlyarm-hardware.so库中的接口,下面中列出HardwareControler类中的接口的定义,这些接口都是类方法,因此不需要创建HardwareControler对象实例: |
− | ==简介== | + | === 通用的输入输出接口 === |
− | 友善电子开发了一个名为libfriendlyarm-hardware.so的函数库,用于Android应用程序访问开发板上的硬件资源,该函数库基于Android-NDK技术开发,提供便利的硬件访问接口,开发者无需掌握过多的嵌入式知识便可使用,有效提高开发进度。<br /><br />
| + | |
− | 本篇文章仅适用于RK3399开发板,包括 NanoPi-NEO4, NanoPi-M4 和 NanoPC-T4。<br />
| + | |
− | 其他平台也有相应的支持,请移步这里查看:[[Android Thing: Android Hardware Programming]]
| + | |
− | | + | |
− | ==支持如下RK3399官方Android BSP==
| + | |
− | * Android 7.1.2
| + | |
− | * Android 8.1
| + | |
− | | + | |
− | ==支持如下RK3399硬件资源==
| + | |
− | * Serial Port
| + | |
− | * GPIO
| + | |
− | * ADC
| + | |
− | * PWM
| + | |
− | * I2C
| + | |
− | * RTC
| + | |
− | * Watch dog
| + | |
− | * SPI
| + | |
− | 等等, 接口包括I2C, SPI, GPIO常用的接口。<br />
| + | |
− | [[File:NanoPC-T4+OLED.jpg|frameless|450px|Smart4418SDK+OLED]]
| + | |
− | | + | |
− | ==支持的开发板== | + | |
− | * NanoPi-NEO4
| + | |
− | * NanoPi-M4
| + | |
− | * NanoPC-T4
| + | |
− | * 其他开发板请移步这里查看:[[Android Thing: Android Hardware Programming]]
| + | |
− | | + | |
− | ==开源Android示例==
| + | |
− | 所有硬件访问的示例程序均已集成到 Android 的源代码当中,位于 Android7.1.2 和 Android8.1 源代码的以下目录:vendor/friendlyelec/apps,也可以单独网上下载,下表中列出各个 Demo 的源代码地址:
| + | |
− | ===Android8.1===
| + | |
| ::{| class="wikitable" | | ::{| class="wikitable" |
| |- | | |- |
− | | style="background: PaleTurquoise; color: black" colspan="2"| '''Android8.1示例''' | + | | style="background: PaleTurquoise; color: black" | '''接口名称''' |
| + | | style="background: PaleTurquoise; color: black" |'''参数与返回值说明''' |
| + | | style="background: PaleTurquoise; color: black" |'''功能说明''' |
| |- | | |- |
− | |Serial Port | + | | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/SerialPortDemo
| + | |
− | |-
| + | |
− | |GPIO
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/GPIO_LED_Demo
| + | |
− | |-
| + | |
− | |ADC
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/ADCDemo
| + | |
− | |-
| + | |
− | |PWM
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/PWMDemo
| + | |
− | |-
| + | |
− | |I2C
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/I2C_LCD1602_Demo
| + | |
− | |-
| + | |
− | |RTC
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/RTC_Demo
| + | |
− | |-
| + | |
− | |Watch dog
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/WatchDogDemo
| + | |
− | |-
| + | |
− | |SPI
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/SPI_OLED_Demo
| + | |
− | |-
| + | |
− | |}
| + | |
− | ===Android7.1.2===
| + | |
− | ::{| class="wikitable"
| + | |
− | |-
| + | |
− | | style="background: PaleTurquoise; color: black" colspan="2"| '''Android7.1.2示例'''
| + | |
− | |-
| + | |
− | |Serial Port
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/SerialPortDemo
| + | |
− | |-
| + | |
− | |GPIO
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/GPIO_LED_Demo
| + | |
− | |-
| + | |
− | |ADC
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/ADCDemo
| + | |
− | |-
| + | |
− | |PWM
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/PWMDemo
| + | |
− | |-
| + | |
− | |I2C
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/I2C_LCD1602_Demo
| + | |
− | |-
| + | |
− | |RTC
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/RTC_Demo
| + | |
− | |-
| + | |
− | |Watch dog
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/WatchDogDemo
| + | |
− | |-
| + | |
− | |SPI
| + | |
− | |style="width: 90%;"|
| + | |
− | https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/SPI_OLED_Demo
| + | |
− | |-
| + | |
− | |}
| + | |
− | | + | |
− | | + | |
− | ==如何在自已的程序中使用硬件访问库==
| + | |
− | ===Step1) 集成libfriendlyarm-hardware.so到你的工程目录===
| + | |
− | 克隆以下仓库到本地:
| + | |
− | <syntaxhighlight lang="bash">
| + | |
− | git clone https://github.com/friendlyarm/android-libfriendlyarm-hardware.git
| + | |
− | </syntaxhighlight>
| + | |
− | 接着复制 libs 目录下的所有内容到你的工程目录下,然后在你的Android项目的src目录下创建com/friendlyarm目录,将java/AndroidSDK目录拷贝进去即可,最后的目录的结构看上去是这样的 (注:AndroidStudio的项目可能会稍有不同,但大致如此):<br />
| + | |
− | <syntaxhighlight lang="bash">
| + | |
− | YourProject/
| + | |
− | ├── AndroidManifest.xml
| + | |
− | ├── libs
| + | |
− | │ ├── arm64-v8a
| + | |
− | │ │ └── libfriendlyarm-hardware.so
| + | |
− | │ └── armeabi
| + | |
− | │ └── libfriendlyarm-hardware.so
| + | |
− | ├── src
| + | |
− | │ └── com
| + | |
− | │ └── friendlyarm
| + | |
− | │ ├── AndroidSDK
| + | |
− | │ │ ├── BoardType.java
| + | |
− | │ │ ├── FileCtlEnum.java
| + | |
− | │ │ ├── GPIOEnum.java
| + | |
− | │ │ ├── HardwareControler.java
| + | |
− | │ │ ├── SPIEnum.java
| + | |
− | │ │ ├── SPI.java
| + | |
− | │ │ └── WatchDogEnum.java
| + | |
− | </syntaxhighlight>
| + | |
− | 使用以下方法导入它们,主要的接口都集中在 HardwareControler.java文件中:
| + | |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
− | import com.friendlyarm.AndroidSDK.HardwareControler;
| + | int openSerialPortEx( |
− | import com.friendlyarm.AndroidSDK.SPIEnum;
| + | String devName, |
− | import com.friendlyarm.AndroidSDK.GPIOEnum;
| + | long baud, |
− | import com.friendlyarm.AndroidSDK.FileCtlEnum;
| + | int dataBits, |
− | import com.friendlyarm.AndroidSDK.BoardType;
| + | int stopBits, |
| + | String parityBit, |
| + | String flowCtrl |
| + | ) |
| </syntaxhighlight> | | </syntaxhighlight> |
− | ===Step2) 让你的app拥有system权限===
| + | || |
− | 你的app需要拥有system权限,才能访问硬件资源; <br />
| + | 参数说明:<br /> |
− | 请参考下面的方法修改你 app 的 AndroidManifest.xml 和 Android.mk这两个文件; <br />
| + | devName: 串口设备文件名,可选的值有:<br /> |
− | 并且最好将你的app放到Android源码中去编译,这一步不是必需的,但是建议这么做,如果你的app在外部编译,你需要对apk进行签名才能让你的app拥有system权限(新手不太建议,过程比较繁琐)。<br />
| + | /dev/ttyS4<br /> |
− | ====修改AndroidManifest.xml====
| + | baud: 波特率 <br /> |
− | 在应用程序的AndroidManifest.xml中的manifest节点中加入以下属性:
| + | dataBits: 数据位 (取值 5~8,一般用8 )<br /> |
− | <syntaxhighlight lang="bash">
| + | stopBits: 停止位 (取值 1~2,一般用1 )<br /> |
− | android:sharedUserId="android.uid.system"
| + | parityBit: 奇偶校验位(取值为单个字母,O表示奇校验,E表示偶校验,N表示无校验)<br /> |
− | </syntaxhighlight> | + | flowCtrl: 数据流控制(取值为单个字母,H表示硬件流控制,S表示软件流控制,N表示不使用数据流控制)<br /> |
− | ====修改Android.mk====
| + | 返回值说明:<br /> |
− | 编写一个Android.mk文件(最简单的方法就是拷贝示例中的Android.mk文件),修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行:
| + | 成功打开串口时,将返回串口的文件描述符,用该描述符可进行 read、write和select等操作,如果打开失败,则返回 -1<br /> |
− | <syntaxhighlight lang="java"> | + | || |
− | LOCAL_PATH:= $(call my-dir)
| + | 打开指定的串口设备,并返回文件描述符。 |
− | include $(CLEAR_VARS)
| + | |
− | | + | |
− | LOCAL_SRC_FILES := $(call all-subdir-java-files)
| + | |
− | | + | |
− | LOCAL_PACKAGE_NAME := 你的项目名
| + | |
− | | + | |
− | LOCAL_CERTIFICATE := platform
| + | |
− | LOCAL_MODULE_TAGS := optional
| + | |
− | LOCAL_CFLAGS := -lfriendlyarm-hardware
| + | |
− | | + | |
− | include $(BUILD_PACKAGE)
| + | |
− | </syntaxhighlight> | + | |
− | ===Step3) 在 Android源代码中编译你的app===
| + | |
− | 先在 Android源代码根目录调用 setenv.sh 导出环境变量,然后进入你的 app 目录,使用mm命令编译; <br />
| + | |
− | 例子:编译 GPIO_LED_Demo: <br />
| + | |
− | <syntaxhighlight lang="bash">
| + | |
− | cd rk3399-android-8.1
| + | |
− | . setenv.sh
| + | |
− | cd vendor/friendlyelec/apps/GPIO_LED_Demo
| + | |
− | mm
| + | |
− | </syntaxhighlight> | + | |
− | | + | |
− | ==RK3399平台Android硬件资源的程序访问==
| + | |
− | ===Serial Port===
| + | |
− | 目前可用的串口是UART4,设备名称为/dev/ttyS4,其他串口资源如下表所示,你也可以使用USB转串口来扩展:
| + | |
− | ::{| class="wikitable"
| + | |
− | |- | + | |
− | |串口设备 || 串口资源占用情况
| + | |
− | |-
| + | |
− | |UART0 || 已被蓝牙占用
| + | |
− | |-
| + | |
− | |UART1 || 已被千兆以太网占用
| + | |
− | |-
| + | |
− | |UART2 || 已被作为调试串口
| + | |
− | |-
| + | |
− | |UART3 || 已被千兆以太网占用
| + | |
| |- | | |- |
− | |UART4 || 空闲,设备名称为 /dev/ttyS4 (注:需使用20180618之后的ROM)
| |
| |} | | |} |
− | | + | === Serial port === |
− | Android硬件库为串口API:
| + | |
| ::{| class="wikitable" | | ::{| class="wikitable" |
| |- | | |- |
− | | style="background: PaleTurquoise; color: black" | '''接口名称''' | + | | style="background: PaleTurquoise; color: black" | '''接口名称''' |
− | | style="background: PaleTurquoise; color: black" |'''参数与返回值说明''' | + | | style="background: PaleTurquoise; color: black" |'''参数与返回值说明''' |
| | style="background: PaleTurquoise; color: black" |'''功能说明''' | | | style="background: PaleTurquoise; color: black" |'''功能说明''' |
| |- | | |- |
Line 206: |
Line 44: |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
| int openSerialPortEx( | | int openSerialPortEx( |
− | String devName, | + | String devName, |
| long baud, | | long baud, |
| int dataBits, | | int dataBits, |
Line 229: |
Line 67: |
| |- | | |- |
| |} | | |} |
− |
| |
− | 串口的读写使用以下通用接口:
| |
− | <syntaxhighlight lang="c">
| |
− | HardwareControler.select //轮询串口是否有数据可写或可读
| |
− | HardwareControler.read //读取串口数据
| |
− | HardwareControler.write //写数据到串口
| |
− | HardwareControler.close //关闭设备
| |
− | </syntaxhighlight>
| |
− | ===GPIO===
| |
− |
| |
− | ===ADC===
| |
− |
| |
− | ===PWM===
| |
− |
| |
− | ===I2C===
| |
− |
| |
− | ===RTC===
| |
− | 可以直接使用cat和echo操作/sys/class/rtc/rtc0/下面的接口。
| |
− | 比如查看当前RTC的日期和时间:
| |
− | <syntaxhighlight lang="bash">
| |
− | cat /sys/class/rtc/rtc0/date
| |
− | # 2018-10-20
| |
− | cat /sys/class/rtc/rtc0/time
| |
− | # 08:20:14
| |
− | </syntaxhighlight>
| |
− | 设置开机时间,如设置120秒后开机:
| |
− | <syntaxhighlight lang="bash">
| |
− | #120秒后定时开机
| |
− | echo +120 > /sys/class/rtc/rtc0/wakealarm
| |
− | </syntaxhighlight>
| |
− |
| |
− | ===Watch dog===
| |
− |
| |
− | ===SPI===
| |
− |
| |
− |
| |
− | ==开发资料==
| |
− | * 中文API文档:https://github.com/friendlyarm/AndroidHardwareAccess/blob/master/友善电子Android硬件开发指南.pdf
| |
在应用层,可透过上一章节中的HardwareControler类来调用libfriendlyarm-hardware.so库中的接口,下面中列出HardwareControler类中的接口的定义,这些接口都是类方法,因此不需要创建HardwareControler对象实例: