Difference between revisions of "FriendlyThings for Rockchip/zh"
(updated by API) |
(updated by API) |
||
(34 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | [[ | + | [[FriendlyThings for Rockchip|English]]<br /><br /> |
+ | 注:本篇所述仅适用于友善电子出品的Rockchip平台主板,若需其他平台请参考 [[FriendlyThings/zh]] | ||
+ | <br /> | ||
+ | {{FriendlyThings Introduction/zh}} | ||
+ | {{FriendlyThings AndroidVersion for Rockchip/zh}} | ||
+ | {{FriendlyThings Boards for Rockchip/zh}} | ||
+ | {{FriendlyThings Installation Guide/zh}} | ||
+ | ==函数库(libfriendlyarm-things.so)接口说明== | ||
+ | 请参考这份WiKi文档:[[FriendlyThings APIs/zh]] | ||
− | == | + | ==硬件资源的程序访问== |
− | + | ===Serial Port=== | |
− | + | 内核默认启用了以下串口可供测试(实际以内核dts配置为准),要使用更多串口可以自行配置内核dts: | |
− | + | {| class="wikitable" | |
+ | |- | ||
+ | ! CPU | ||
+ | ! Model | ||
+ | ! Port | ||
+ | ! Device Node | ||
+ | |- | ||
+ | | RK3588 | ||
+ | | NanoPC-T6 | ||
+ | | UART6 | ||
+ | | /dev/ttyS6 | ||
+ | |- | ||
+ | | RK3588S | ||
+ | | NanoPi-R6S/R6C | ||
+ | | UART5 | ||
+ | | /dev/ttyS5 | ||
+ | |- | ||
+ | | RK3568 | ||
+ | | NanoPi-R5S | ||
+ | | UART9 | ||
+ | | /dev/ttyS9 | ||
+ | |- | ||
+ | | RK3399 | ||
+ | | NanoPC-T4 | ||
+ | | UART4 | ||
+ | | /dev/ttyS4 | ||
+ | |} | ||
− | == | + | ====串口读写的接口说明==== |
− | + | <syntaxhighlight lang="c"> | |
− | + | HardwareControler.openSerialPortEx //打开串口设备 | |
+ | HardwareControler.select //轮询串口是否有数据可写或可读 | ||
+ | HardwareControler.read //读取串口数据 | ||
+ | HardwareControler.write //写数据到串口 | ||
+ | HardwareControler.close //关闭设备 | ||
+ | </syntaxhighlight> | ||
+ | 接口说明请参考:[[FriendlyThings APIs/zh]] | ||
− | == | + | ===GPIO=== |
− | + | 通过 sysfs 方式控制来 GPIO,是先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO编号,使得该 GPIO 的操作接口从内核空间暴露到用户空间,然后就可以操作引脚的 direction 和 value 等,direction 控制 GPIO 方向,而 value 可控制 GPIO 输出或获得 GPIO 输入。<br /> | |
− | + | <br /> | |
− | + | 下面列出内核默认配置成GPIO功能的引脚(实际以内核dts配置为准): | |
− | + | ====NanoPC T6==== | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | == | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | == | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
::{| class="wikitable" | ::{| class="wikitable" | ||
|- | |- | ||
− | | | + | | style="background: PaleTurquoise; color: black" | '''Physical Index''' |
+ | | style="background: PaleTurquoise; color: black" |'''GPIO Index''' | ||
|- | |- | ||
− | | | + | |Pin7||106 |
|- | |- | ||
− | | | + | |Pin12||111 |
|- | |- | ||
− | | | + | |Pin15||39 |
|- | |- | ||
− | | | + | |Pin16||107 |
+ | |- | ||
+ | |Pin18||108 | ||
+ | |- | ||
+ | |Pin26||40 | ||
|- | |- | ||
− | |||
|} | |} | ||
− | + | ====NanoPi R6C==== | |
− | + | ||
::{| class="wikitable" | ::{| class="wikitable" | ||
|- | |- | ||
− | | style="background: PaleTurquoise; color: black" | ''' | + | | style="background: PaleTurquoise; color: black" | '''Physical Index''' |
− | | style="background: PaleTurquoise; color: black" |''' | + | | style="background: PaleTurquoise; color: black" |'''GPIO Index''' |
− | + | ||
|- | |- | ||
− | | | + | |Pin7||128 |
− | + | |- | |
− | + | |Pin11||129 | |
− | + | |- | |
− | + | |Pin13||130 | |
− | + | |- | |
− | + | |Pin15||133 | |
− | + | |- | |
− | + | |Pin16||134 | |
− | + | |- | |
− | + | |Pin18||137 | |
− | || | + | |- |
− | + | |Pin22||138 | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | || | + | |
− | + | ||
|- | |- | ||
+ | |} | ||
+ | ====NanoPi R6S==== | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''Physical Index''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''GPIO Index''' | ||
+ | |- | ||
+ | |Pin3||43 | ||
+ | |- | ||
+ | |Pin5||41 | ||
+ | |- | ||
+ | |Pin6||44 | ||
+ | |- | ||
+ | |Pin7||42 | ||
+ | |- | ||
+ | |Pin9||47 | ||
+ | |- | ||
+ | |Pin10||46 | ||
+ | |- | ||
+ | |} | ||
+ | ====NanoPi R5S==== | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''Physical Index''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''GPIO Index''' | ||
+ | |- | ||
+ | |Pin3||115 | ||
+ | |- | ||
+ | |Pin5||114 | ||
+ | |- | ||
+ | |Pin6||97 | ||
+ | |- | ||
+ | |Pin7||113 | ||
+ | |- | ||
+ | |Pin11||116 | ||
+ | |- | ||
+ | |Pin12||117 | ||
+ | |- | ||
+ | |} | ||
+ | ====NanoPC T4==== | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''物理序号''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''GPIO编号''' | ||
+ | |- | ||
+ | |Pin11||33 | ||
+ | |- | ||
+ | |Pin12||50 | ||
+ | |- | ||
+ | |Pin15||36 | ||
+ | |- | ||
+ | |Pin16||54 | ||
+ | |- | ||
+ | |Pin18||55 | ||
+ | |- | ||
+ | |Pin22||56 | ||
+ | |- | ||
+ | |Pin37||96 | ||
+ | |- | ||
+ | |Pin38||125 | ||
+ | |- | ||
+ | |Pin40||126 | ||
+ | |} | ||
+ | ====NanoPi M4/M4v2/M4B/NEO4==== | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''物理序号''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''Linux索引号''' | ||
+ | |- | ||
+ | |Pin11||33 | ||
+ | |- | ||
+ | |Pin12||50 | ||
+ | |- | ||
+ | |Pin15||36 | ||
+ | |- | ||
+ | |Pin16||54 | ||
+ | |- | ||
+ | |Pin18||55 | ||
+ | |- | ||
+ | |Pin22||56 | ||
+ | |} | ||
+ | ====SOM-RK3399/SOM-RK3399v2==== | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''Physical Index''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''GPIO Index''' | ||
+ | |- | ||
+ | |Pin7||41 | ||
+ | |- | ||
+ | |Pin9||42 | ||
|} | |} | ||
− | + | ====GPIO接口说明==== | |
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
− | HardwareControler. | + | HardwareControler.exportGPIOPin //导出GPIO |
− | HardwareControler. | + | HardwareControler.setGPIODirection //改变GPIO的方向 |
− | HardwareControler. | + | HardwareControler.getGPIODirection //获得当前GPIO的方向 |
− | HardwareControler. | + | HardwareControler.setGPIOValue //向引脚输出高电平或低电平 |
+ | HardwareControler.getGPIOValue //获得引脚的输入(当前的值) | ||
+ | HardwareControler.unexportGPIOPin //取消导出 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | 接口说明请参考:[[FriendlyThings APIs/zh]] | |
+ | ====GPIO示例说明==== | ||
+ | 可以用LED配件来测试GPIO示例,在界面上对引脚输出高电平时,LED亮,低电平时,LCD灭。 | ||
+ | [[File:rk3399-android-gpio.png|frameless|GPIO]] | ||
===ADC=== | ===ADC=== | ||
− | + | 在 Android 下用标准的文件读取接口就可以读取,你可以将一个可调电阻配件连接到开发板上进行测试。 | |
+ | ====RK3588==== | ||
+ | Channel2对应的文件节点如下所示, 此ADC可用于查询USB-C的输入电压: | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''频道''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''文件节点''' | ||
+ | |- | ||
+ | |Channel 2||/sys/devices/platform/fec10000.saradc/iio:device0/in_voltage2_raw | ||
+ | |} | ||
+ | ====RK3568==== | ||
+ | Channel2对应的文件节点如下所示, 此ADC可用于查询USB-C的输入电压: | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''频道''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''文件节点''' | ||
+ | |- | ||
+ | |Channel 2||/sys/devices/platform/fe720000.saradc/iio:device0/in_voltage2_raw | ||
+ | |} | ||
+ | ====RK3399==== | ||
+ | RK3399引出了三路ADC,channel为0, 2, 3,对应的文件节点为: | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''频道''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''文件节点''' | ||
+ | |- | ||
+ | |Channel 0||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage0_raw | ||
+ | |- | ||
+ | |Channel 2||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage2_raw | ||
+ | |- | ||
+ | |Channel 3||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage3_raw | ||
+ | |} | ||
===PWM=== | ===PWM=== | ||
+ | ====NanoPC-T6==== | ||
+ | 默认已配置 Pin32 为PWM,可以使用LED进行测试 | ||
+ | ====NanoPi-R6C==== | ||
+ | 默认已配置 Pin29 为PWM,可以使用LED进行测试 | ||
+ | ====RK3399==== | ||
+ | <b>Note: 默认情况下,PWM接口已经用于连接风扇,如果您想自己控制PWM,则需要先禁用风扇,<br /> | ||
+ | 请参考这篇文章: </b>[[Template:RK3399 Android PWMFan/zh]]<br /> | ||
+ | RK3399开发板也是通过sysfs方式来控制PWM,直接操作 /sys/class/pwm/pwmchip1 下的文件节点即可,下面以在命令行操作PWM风扇风速作为示例: | ||
+ | =====PWM接口说明===== | ||
+ | * 将PWM0暴露到用户空间 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | echo 0 > /sys/class/pwm/pwmchip1/export | ||
+ | </syntaxhighlight> | ||
+ | * 通过设置PWM的period和duty_cycle来控制风速 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable | ||
+ | echo 50000 > /sys/class/pwm/pwmchip1/pwm0/period | ||
+ | echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable | ||
+ | echo 45000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle | ||
+ | </syntaxhighlight> | ||
+ | =====PWM示例说明===== | ||
+ | 可以连接一个PWM风扇(3针)到NanoPC-T4的风扇接口来测试PWM示例。<br /> | ||
+ | [[File:rk3399-android-pwm.png|frameless|PWM]] | ||
===I2C=== | ===I2C=== | ||
+ | ====RK3399==== | ||
+ | 运行I2C Demo需要将一个LCD1602的模块连接到NanoPC-T4的以下引脚: | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''物理序号''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''I2C功能''' | ||
+ | |- | ||
+ | |Pin3||I2C2_SDA(3V) | ||
+ | |- | ||
+ | |Pin4||VCC5V0_SYS | ||
+ | |- | ||
+ | |Pin5||I2C2_SCL(3V) | ||
+ | |- | ||
+ | |Pin6||GND | ||
+ | |} | ||
+ | |||
+ | 如下图所示:<br /> | ||
+ | [[File:NanoPC-T4+OLED.jpg|frameless|450px]] | ||
===RTC=== | ===RTC=== | ||
− | + | '''注:定时开关机只有某些型号支持,例如NanoPC-T4'''<br /> | |
− | + | 通过 /sys/class/rtc/rtc0/下面的接口来操作RTC,比如查看当前RTC的日期和时间:<br /> | |
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cat /sys/class/rtc/rtc0/date | cat /sys/class/rtc/rtc0/date | ||
Line 115: | Line 291: | ||
echo +120 > /sys/class/rtc/rtc0/wakealarm | echo +120 > /sys/class/rtc/rtc0/wakealarm | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | [[File:rk3399-android-rtc.png|frameless|RTC]] | ||
===Watch dog=== | ===Watch dog=== | ||
− | + | 看门狗的操作比较简单,打开设备 /dev/watchdog 并定时写入字符即可,如果系统出现问题导致没有写入字符,设备会过一段时间自动重启: | |
+ | <syntaxhighlight lang="java"> | ||
+ | mWatchDogFD = HardwareControler.open("/dev/watchdog", FileCtlEnum.O_WRONLY); | ||
+ | HardwareControler.write(mWatchDogFD, "a".getBytes()); | ||
+ | </syntaxhighlight> | ||
+ | [[File:rk3399-android-watchdog.png|frameless|WatchDog]] | ||
===SPI=== | ===SPI=== | ||
+ | ====RK3399==== | ||
+ | =====启用SPI===== | ||
+ | SPI由于与UART4共用引脚,所以需要修改内核DTS文件,修改方法如下: <br /> | ||
+ | 编辑内核目录下的dts文件 arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi: | ||
+ | <syntaxhighlight lang="c"> | ||
+ | cd ANDROID_SOURCE/kernel | ||
+ | vim arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi | ||
+ | </syntaxhighlight> | ||
+ | 其中,ANDROID_SOURCE请替换为真实的 Android7或Android8源代码目录。 | ||
+ | 首先找到 spi1 的定义: | ||
+ | <syntaxhighlight lang="c"> | ||
+ | &spi1 { | ||
+ | status = "disabled"; // 将其中的 disabled 改为 okay | ||
+ | </syntaxhighlight> | ||
+ | 然后再在 rk3399-nanopi4-common.dtsi 文件到找到 uart4 的定义: | ||
+ | <syntaxhighlight lang="c"> | ||
+ | &uart4 { | ||
+ | status = "okay"; // 将其中的 okay 改为 disabled | ||
+ | </syntaxhighlight> | ||
+ | 最后重新编译内核: | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | cd ANDROID_SOURCE/ | ||
+ | ./build-nanopc-t4.sh -K -M | ||
+ | </syntaxhighlight> | ||
+ | 更新 rockdev/Image-nanopc_t4/resource.img 到开发板即可,可以将resource.img拷贝到安装有 eflasher 系统的TF卡中,位置是FriendlyARM分区的androidX 目录,替换里面的resource.img文件,然后用TF卡重刷系统。 | ||
− | == | + | =====SPI示例===== |
− | + | SPI示例默认没有预装,需要手动编译,方法是修改Android源代码的以下文件:<br /> | |
+ | vendor/friendlyelec/apps# vi device-partial.mk<br /> | ||
+ | 去掉前面的注释:<br /> | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | # PRODUCT_PACKAGES += SPI-OLED | ||
+ | </syntaxhighlight> | ||
+ | 然后重新编译 Android源代码。<br /> | ||
+ | <br /> | ||
+ | 运行SPI示例需要在NanoPC-T4上连接一个 SPI接口的OLED,规格为0.96寸的128x64屏。<br /> | ||
+ | <br /> | ||
+ | 屏幕上有7个引脚,与开发板用母对母杜邦线连接,接法如下表:<br /> | ||
+ | ::{| class="wikitable" | ||
+ | |- | ||
+ | | style="background: PaleTurquoise; color: black" | '''OLED引脚''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''功能''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''NanoPC-T4引脚编号''' | ||
+ | | style="background: PaleTurquoise; color: black" |'''备注''' | ||
+ | |- | ||
+ | |GND|| ||Pin6 GND || | ||
+ | |- | ||
+ | |VCC|| ||Pin2 VCC5V || | ||
+ | |- | ||
+ | |DO||SCLK||Pin23 (SPI1_CLK(3V) ||时钟信号,由主设备产生 | ||
+ | |- | ||
+ | |DI||MOSI||Pin19 (SPI1_TXD) ||主设备数据输出,从设备数据输入 | ||
+ | |- | ||
+ | |RES|| ||Pin16 (GPIO1_C6(3V)) || | ||
+ | |- | ||
+ | |D/C|| ||Pin12 (GPIO1_C2) || | ||
+ | |- | ||
+ | |CS||CS0||Pin24 (SPI1_CSn0) ||从设备使能信号,由主设备控制 | ||
+ | |} | ||
+ | <br /> | ||
+ | ====SPI接口说明==== | ||
+ | 请参考:[[FriendlyThings APIs/zh]] | ||
+ | |||
+ | ==示例程序下载地址== | ||
+ | 所有硬件访问的示例程序均已集成到 Android 的源代码当中,位于 Android7.1.2 和 Android8.1 源代码的以下目录:vendor/friendlyelec/apps,也可以单独网上下载,下表中列出各个 Demo 的源代码地址: | ||
+ | {{FriendlyThings Android8 Demos}} | ||
+ | {{FriendlyThings Android7 Demos}} |
Latest revision as of 11:28, 17 August 2023
English
注:本篇所述仅适用于友善电子出品的Rockchip平台主板,若需其他平台请参考 FriendlyThings/zh
Contents
1 简介
FriendlyThings是友善电子开发的一套安卓硬件开发SDK(函数库),安卓软件开发者可以通过它在Android应用程序中编程访问和控制ARM主板上的各种硬件资源,比如Uart, SPI, I2C, GPIO等接口,它基于Android-NDK技术开发,开发者无需掌握底层的嵌入式知识(尤其是驱动程序),就可以构建基于安卓系统的各种IoT物联网应用。
2 Android版本
我们提供的Android BSP已经包含FriendlyThings SDK(libfriendlyarm-things.so),包含如下Android平台版本:
- Android 12 (rk3568 & rk3588)
BSP source code download link: http://112.124.9.243:3000/friendlyelec/rk35xx-android12
Latest ROM download link: http://download.friendlyelec.com/NanoPC-T6
- Android 8.1-rk3399
BSP source code download link: https://gitlab.com/friendlyelec/rk3399-android-8.1
BSP source code location on the network disk: sources/rk3399-android-8.1.git-YYYYMMDD.tgz
Latest ROM download link: http://download.friendlyelec.com/NanoPC-T4
- Android 7.1.2-rk3399
BSP source code download link: https://gitlab.com/friendlyelec/rk3399-nougat
BSP source code location on the network disk: sources/rk3399-android-7.git-YYYYMMDD.tgz
Latest ROM download link: http://download.friendlyelec.com/NanoPC-T4
3 开发板型号列表
FriendlyThings SDK(libfriendlyarm-things.so)适用于友善电子出品的如下RK3399/RK3568/RK3588系列主板:
- NanoPC-T6
- NanoPi-R6S/R6C
- NanoPi-R5S/R5C
- NanoPC-T4
- NanoPi M4 (需外接eMMC模块)
- NanoPi NEO4 (需外接eMMC模块)
FriendlyThings也可以支持其他平台安卓主板,如三星S5P4418/S5P6818,三星S5PV210,全志H3/H5等平台,具体请查看这里FriendlyThings/zh
4 快速使用入门
4.1 (第1步) 集成libfriendlyarm-things.so到你的app
克隆以下仓库到本地:
git clone https://github.com/friendlyarm/friendlythings-sdk
接着复制 libs 目录下的所有内容到你的工程目录下,然后在你的Android项目的src目录下创建com/friendlyarm目录,将java/FriendlyThings目录拷贝进去即可,最后的目录的结构看上去是这样的 (注:AndroidStudio的项目可能会稍有不同,但大致如此):
YourProject/
├── AndroidManifest.xml
├── libs
│ ├── arm64-v8a
│ │ └── libfriendlyarm-things.so
│ └── armeabi
│ └── libfriendlyarm-things.so
├── src
│ └── com
│ └── friendlyarm
│ ├── FriendlyThings
│ │ ├── BoardType.java
│ │ ├── FileCtlEnum.java
│ │ ├── GPIOEnum.java
│ │ ├── HardwareControler.java
│ │ ├── SPIEnum.java
│ │ ├── SPI.java
│ │ └── WatchDogEnum.java
使用以下方法导入它们,主要的接口都集中在 HardwareControler.java文件中:
import com.friendlyarm.FriendlyThings.HardwareControler; import com.friendlyarm.FriendlyThings.SPIEnum; import com.friendlyarm.FriendlyThings.GPIOEnum; import com.friendlyarm.FriendlyThings.FileCtlEnum; import com.friendlyarm.FriendlyThings.BoardType;
4.2 (第2步) 让你的app拥有system权限
你的app需要拥有system权限,才能访问硬件资源;
请参考下面的方法修改你 app 的 AndroidManifest.xml 和 Android.mk这两个文件;
并且最好将你的app放到Android源码中去编译,这一步不是必需的,但是建议这么做,如果你的app在外部编译,你需要对apk进行签名才能让你的app拥有system权限(新手不太建议,过程比较繁琐)。
4.2.1 修改AndroidManifest.xml
在应用程序的AndroidManifest.xml中的manifest节点中加入以下属性:
android:sharedUserId="android.uid.system"
4.2.2 修改Android.mk
编写一个Android.mk文件(最简单的方法就是拷贝示例中的Android.mk文件),修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行:
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)
4.3 (最后1步) 在 Android源代码中编译你的app
先在 Android源代码根目录调用 setenv.sh 导出环境变量,然后进入你的 app 目录,使用mm命令编译;
例子:编译 GPIO_LED_Demo,以RK3399平台为例:
cd rk3399-android-8.1 . setenv.sh cd vendor/friendlyelec/apps/GPIO_LED_Demo mm
4.4 一个Android Studio的示例项目
https://github.com/friendlyarm/AndroidStudio-GPIODemo
5 函数库(libfriendlyarm-things.so)接口说明
请参考这份WiKi文档:FriendlyThings APIs/zh
6 硬件资源的程序访问
6.1 Serial Port
内核默认启用了以下串口可供测试(实际以内核dts配置为准),要使用更多串口可以自行配置内核dts:
CPU | Model | Port | Device Node |
---|---|---|---|
RK3588 | NanoPC-T6 | UART6 | /dev/ttyS6 |
RK3588S | NanoPi-R6S/R6C | UART5 | /dev/ttyS5 |
RK3568 | NanoPi-R5S | UART9 | /dev/ttyS9 |
RK3399 | NanoPC-T4 | UART4 | /dev/ttyS4 |
6.1.1 串口读写的接口说明
HardwareControler.openSerialPortEx //打开串口设备 HardwareControler.select //轮询串口是否有数据可写或可读 HardwareControler.read //读取串口数据 HardwareControler.write //写数据到串口 HardwareControler.close //关闭设备
接口说明请参考:FriendlyThings APIs/zh
6.2 GPIO
通过 sysfs 方式控制来 GPIO,是先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO编号,使得该 GPIO 的操作接口从内核空间暴露到用户空间,然后就可以操作引脚的 direction 和 value 等,direction 控制 GPIO 方向,而 value 可控制 GPIO 输出或获得 GPIO 输入。
下面列出内核默认配置成GPIO功能的引脚(实际以内核dts配置为准):
6.2.1 NanoPC T6
Physical Index GPIO Index Pin7 106 Pin12 111 Pin15 39 Pin16 107 Pin18 108 Pin26 40
6.2.2 NanoPi R6C
Physical Index GPIO Index Pin7 128 Pin11 129 Pin13 130 Pin15 133 Pin16 134 Pin18 137 Pin22 138
6.2.3 NanoPi R6S
Physical Index GPIO Index Pin3 43 Pin5 41 Pin6 44 Pin7 42 Pin9 47 Pin10 46
6.2.4 NanoPi R5S
Physical Index GPIO Index Pin3 115 Pin5 114 Pin6 97 Pin7 113 Pin11 116 Pin12 117
6.2.5 NanoPC T4
物理序号 GPIO编号 Pin11 33 Pin12 50 Pin15 36 Pin16 54 Pin18 55 Pin22 56 Pin37 96 Pin38 125 Pin40 126
6.2.6 NanoPi M4/M4v2/M4B/NEO4
物理序号 Linux索引号 Pin11 33 Pin12 50 Pin15 36 Pin16 54 Pin18 55 Pin22 56
6.2.7 SOM-RK3399/SOM-RK3399v2
Physical Index GPIO Index Pin7 41 Pin9 42
6.2.8 GPIO接口说明
HardwareControler.exportGPIOPin //导出GPIO HardwareControler.setGPIODirection //改变GPIO的方向 HardwareControler.getGPIODirection //获得当前GPIO的方向 HardwareControler.setGPIOValue //向引脚输出高电平或低电平 HardwareControler.getGPIOValue //获得引脚的输入(当前的值) HardwareControler.unexportGPIOPin //取消导出
接口说明请参考:FriendlyThings APIs/zh
6.2.9 GPIO示例说明
可以用LED配件来测试GPIO示例,在界面上对引脚输出高电平时,LED亮,低电平时,LCD灭。
6.3 ADC
在 Android 下用标准的文件读取接口就可以读取,你可以将一个可调电阻配件连接到开发板上进行测试。
6.3.1 RK3588
Channel2对应的文件节点如下所示, 此ADC可用于查询USB-C的输入电压:
频道 文件节点 Channel 2 /sys/devices/platform/fec10000.saradc/iio:device0/in_voltage2_raw
6.3.2 RK3568
Channel2对应的文件节点如下所示, 此ADC可用于查询USB-C的输入电压:
频道 文件节点 Channel 2 /sys/devices/platform/fe720000.saradc/iio:device0/in_voltage2_raw
6.3.3 RK3399
RK3399引出了三路ADC,channel为0, 2, 3,对应的文件节点为:
频道 文件节点 Channel 0 /sys/devices/platform/ff100000.saradc/iio:device0/in_voltage0_raw Channel 2 /sys/devices/platform/ff100000.saradc/iio:device0/in_voltage2_raw Channel 3 /sys/devices/platform/ff100000.saradc/iio:device0/in_voltage3_raw
6.4 PWM
6.4.1 NanoPC-T6
默认已配置 Pin32 为PWM,可以使用LED进行测试
6.4.2 NanoPi-R6C
默认已配置 Pin29 为PWM,可以使用LED进行测试
6.4.3 RK3399
Note: 默认情况下,PWM接口已经用于连接风扇,如果您想自己控制PWM,则需要先禁用风扇,
请参考这篇文章: Template:RK3399 Android PWMFan/zh
RK3399开发板也是通过sysfs方式来控制PWM,直接操作 /sys/class/pwm/pwmchip1 下的文件节点即可,下面以在命令行操作PWM风扇风速作为示例:
6.4.3.1 PWM接口说明
- 将PWM0暴露到用户空间
echo 0 > /sys/class/pwm/pwmchip1/export
- 通过设置PWM的period和duty_cycle来控制风速
echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable echo 50000 > /sys/class/pwm/pwmchip1/pwm0/period echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable echo 45000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
6.4.3.2 PWM示例说明
可以连接一个PWM风扇(3针)到NanoPC-T4的风扇接口来测试PWM示例。
6.5 I2C
6.5.1 RK3399
运行I2C Demo需要将一个LCD1602的模块连接到NanoPC-T4的以下引脚:
物理序号 I2C功能 Pin3 I2C2_SDA(3V) Pin4 VCC5V0_SYS Pin5 I2C2_SCL(3V) Pin6 GND
6.6 RTC
注:定时开关机只有某些型号支持,例如NanoPC-T4
通过 /sys/class/rtc/rtc0/下面的接口来操作RTC,比如查看当前RTC的日期和时间:
cat /sys/class/rtc/rtc0/date # 2018-10-20 cat /sys/class/rtc/rtc0/time # 08:20:14
设置开机时间,如设置120秒后开机:
#120秒后定时开机 echo +120 > /sys/class/rtc/rtc0/wakealarm
6.7 Watch dog
看门狗的操作比较简单,打开设备 /dev/watchdog 并定时写入字符即可,如果系统出现问题导致没有写入字符,设备会过一段时间自动重启:
mWatchDogFD = HardwareControler.open("/dev/watchdog", FileCtlEnum.O_WRONLY); HardwareControler.write(mWatchDogFD, "a".getBytes());
6.8 SPI
6.8.1 RK3399
6.8.1.1 启用SPI
SPI由于与UART4共用引脚,所以需要修改内核DTS文件,修改方法如下:
编辑内核目录下的dts文件 arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi:
cd ANDROID_SOURCE/kernel vim arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
其中,ANDROID_SOURCE请替换为真实的 Android7或Android8源代码目录。
首先找到 spi1 的定义:
&spi1 { status = "disabled"; // 将其中的 disabled 改为 okay
然后再在 rk3399-nanopi4-common.dtsi 文件到找到 uart4 的定义:
&uart4 { status = "okay"; // 将其中的 okay 改为 disabled
最后重新编译内核:
cd ANDROID_SOURCE/ ./build-nanopc-t4.sh -K -M
更新 rockdev/Image-nanopc_t4/resource.img 到开发板即可,可以将resource.img拷贝到安装有 eflasher 系统的TF卡中,位置是FriendlyARM分区的androidX 目录,替换里面的resource.img文件,然后用TF卡重刷系统。
6.8.1.2 SPI示例
SPI示例默认没有预装,需要手动编译,方法是修改Android源代码的以下文件:
vendor/friendlyelec/apps# vi device-partial.mk
去掉前面的注释:
# PRODUCT_PACKAGES += SPI-OLED
然后重新编译 Android源代码。
运行SPI示例需要在NanoPC-T4上连接一个 SPI接口的OLED,规格为0.96寸的128x64屏。
屏幕上有7个引脚,与开发板用母对母杜邦线连接,接法如下表:
OLED引脚 功能 NanoPC-T4引脚编号 备注 GND Pin6 GND VCC Pin2 VCC5V DO SCLK Pin23 (SPI1_CLK(3V) 时钟信号,由主设备产生 DI MOSI Pin19 (SPI1_TXD) 主设备数据输出,从设备数据输入 RES Pin16 (GPIO1_C6(3V)) D/C Pin12 (GPIO1_C2) CS CS0 Pin24 (SPI1_CSn0) 从设备使能信号,由主设备控制
6.8.2 SPI接口说明
7 示例程序下载地址
所有硬件访问的示例程序均已集成到 Android 的源代码当中,位于 Android7.1.2 和 Android8.1 源代码的以下目录:vendor/friendlyelec/apps,也可以单独网上下载,下表中列出各个 Demo 的源代码地址:
7.1 Android8.1
7.1.1 Applicable Boards
- NanoPC-T4/NanoPi-M4/NanoPi-NEO4
Android8.1 Demos Serial Port GPIO ADC https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/ADCDemo
PWM https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/PWMDemo
I2C RTC Watch dog SPI
7.2 Android7.1.2
7.2.1 Applicable Boards
- NanoPC-T4/NanoPi-M4/NanoPi-NEO4
Android7.1.2 Demos Serial Port GPIO ADC https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/ADCDemo
PWM https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/PWMDemo
I2C RTC Watch dog SPI