风火轮科技开发一款rk3588s的主板youyeetoo R1,该主板提供40pin扩展管脚,其中提供1路pwm管脚使用。管脚分布如下图所示:
如果要在Android系统里面使用shell命令,需要通过ADB进入Android的命令行窗口。ADB的使用教程请参考 adb调试 一章。通过adb打开Android系统命令行后,操作pwm管脚需要先把pwm设备导出到用户空间。
adb shell setprop persist.sys.root_access 3
adb root
adb remount
adb shell
cat >> /system/bin/setup.sh << EOF
echo 0 > /sys/class/pwm/pwmchip0/export
chmod 666 /sys/class/pwm/pwmchip0/pwm0/*
EOF
Android系统的权限管理是十分严格的,使用c++或者java操作Android根文件系统里的文件或资源需要对应的权限。这里编写的ndk程序是基于 system app的作为模板进行编写。system app请参考创建system app这一章。
#include <jni.h>
#include <string>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
extern "C" JNIEXPORT jstring
#define PERIOD "/sys/class/pwm/pwmchip0/pwm0/period"
#define DUTY_CYCLE "/sys/class/pwm/pwmchip0/pwm0/duty_cycle"
#define ENABLE "/sys/class/pwm/pwmchip0/pwm0/enable"
JNICALL
Java_com_youyeetoo_r1_1pwm_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
int fd_period = open(PERIOD, O_WRONLY);
int fd_dutyPeriod = open(DUTY_CYCLE, O_WRONLY);
int fd_enable = open(ENABLE, O_WRONLY);
if (fd_period < 0 || fd_dutyPeriod < 0 || fd_enable < 0)
{
return env->NewStringUTF("period open fail OR fd_dutyPeriod open fail OR fd_enable open fail");
}
write(fd_period, "10000", 6);
write(fd_dutyPeriod, "5000", 5);
write(fd_enable, "1", 2);
close(fd_period);
close(fd_dutyPeriod);
close(fd_enable);
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
运行程序之后使用示波器,可以看见方波为成功!