如何在Android Things上绕过Java做GPIO [英] How to do GPIO on Android Things bypassing Java

查看:125
本文介绍了如何在Android Things上绕过Java做GPIO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用NDK通过Android事物访问Raspberry Pi上的GPIO,但是尝试了几种方法之后,我总是发现某种安全墙阻止了我的访问.

I've been trying to access GPIO on Raspberry Pi with Android things using NDK, but after trying several approaches I always find some kind of security wall preventing me from accessing it.

动机是我使用Java API从GPIO获得的速度缓慢.作为基本参考,我能够以大约2KHz的频率打开和关闭它,这恰好是什么是Android Things Raspberry Pi GPIO的最大频率?,到目前为止,还没有答案,我在其中添加了有关Java速度的注释.实际上,这项工作是由我在检查该问题时获得的结果所推动的.

The motivation is the sluggish speed I'm getting from GPIO using the Java API. As a basic reference I was able to toggle it on and off at about 2KHz, which happens to be the poorest among this list. See also What is Android Things Raspberry Pi GPIO max frequency?, where so far there's no answer and where I added a comment about java speed. In fact this work was motivated by the results I got when checking for that question.

到目前为止,最好的方法是尝试类似于在Debian下使用sysfs进行的操作.在那种程度上,代码似乎很合理,但是在以root身份运行之后,将应用程序安装为系统应用程序(通过将其移动到/system/app)并在/sys/class/gpio//sys/class/gpio/gpio24/以及/dev/gpiomem这就是我得到的:

The best approach so far is trying something similar to what would take for sysfs under Debian. To that extent, the code seems fair but after running as root, installing the app as system app (by moving it to /system/app) and chmod a+rw several different things under both /sys/class/gpio/ and /sys/class/gpio/gpio24/ and also /dev/gpiomem this was what I got:

01-27 12:54:47.069  8412  8412 I NativeHelper: Call native = hello from helper java class
01-27 12:54:47.079  8412  8412 I NativeHelper: Open pin true
01-27 12:54:47.080  8412  8412 F libc    : Fatal signal 4 (SIGILL), code 1, fault addr 0xaf2e039c in tid 8412 (le.thingssample)
01-27 12:54:47.081   128   128 W         : debuggerd: handling request: pid=8412 uid=10028 gid=10028 tid=8412
01-27 12:54:47.066  8412  8412 I le.thingssample: type=1400 audit(0.0:211): avc: denied { write } for name="export" dev="sysfs" ino=854 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
01-27 12:54:47.076  8412  8412 I le.thingssample: type=1400 audit(0.0:212): avc: denied { open } for path="/sys/class/gpio/export" dev="sysfs" ino=854 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
01-27 12:54:47.166  8427  8427 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-27 12:54:47.166  8427  8427 F DEBUG   : Build fingerprint: 'generic/iot_rpi3/rpi3:7.0/NIF73/3565696:userdebug/test-keys'
01-27 12:54:47.166  8427  8427 F DEBUG   : Revision: '0'
01-27 12:54:47.166  8427  8427 F DEBUG   : ABI: 'arm'
01-27 12:54:47.167  8427  8427 F DEBUG   : pid: 8412, tid: 8412, name: le.thingssample  >>> com.amazingapps.sample.thingssample <<<
01-27 12:54:47.167  8427  8427 F DEBUG   : signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0xaf2e039c
01-27 12:54:47.167  8427  8427 F DEBUG   :     r0 00000000  r1 b1f5e59f  r2 b1f5e59f  r3 af2e1c55
01-27 12:54:47.167  8427  8427 F DEBUG   :     r4 00000000  r5 be8e35fc  r6 acca3230  r7 be8e35d8
01-27 12:54:47.167  8427  8427 F DEBUG   :     r8 be8e36f8  r9 acc85400  sl 00000000  fp be8e3684
01-27 12:54:47.168  8427  8427 F DEBUG   :     ip be8e3590  sp be8e3598  lr ae7fbd2b  pc af2e039c  cpsr 60000030
01-27 12:54:47.170  8427  8427 F DEBUG   :
01-27 12:54:47.170  8427  8427 F DEBUG   : backtrace:
01-27 12:54:47.170  8427  8427 F DEBUG   :     #00 pc 0000139c  /data/app/com.amazingapps.sample.thingssample-1/lib/arm/libsample.so (Java_com_amazingapps_sample_thingssample_ndk_NativeHelper_doAll+59)
01-27 12:54:47.170  8427  8427 F DEBUG   :     #01 pc 002c8cb3  /data/app/com.amazingapps.sample.thingssample-1/oat/arm/base.odex (offset 0x2af000)
01-27 12:54:48.133   408  8432 W ActivityManager:   Force finishing activity com.amazingapps.sample.thingssample/.view.MainActivity
01-27 12:54:48.137   128   128 W         : debuggerd: resuming target 8412
01-27 12:54:48.138   408   427 I BootReceiver: Copying /data/tombstones/tombstone_02 to DropBox (SYSTEM_TOMBSTONE)
01-27 12:54:48.228  8433  8433 W crash_reporter: Received crash notification for app_process32[8412] sig 4, user 10028 (handling)
01-27 12:54:48.233  8433  8433 I crash_reporter: State of crashed process [8412]: S (sleeping)
01-27 12:54:48.226  8433  8433 I crash_reporter: type=1400 audit(0.0:213): avc: denied { search } for name="8412" dev="proc" ino=214991 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=dir permissive=1
01-27 12:54:48.226  8433  8433 I crash_reporter: type=1400 audit(0.0:214): avc: denied { read } for name="exe" dev="proc" ino=217417 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=lnk_file permissive=1
01-27 12:54:48.226  8433  8433 I crash_reporter: type=1400 audit(0.0:215): avc: denied { read } for scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=file permissive=1
01-27 12:54:48.226  8433  8433 I crash_reporter: type=1400 audit(0.0:216): avc: denied { open } for path="/proc/8412/status" dev="proc" ino=216902 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=file permissive=1
01-27 12:54:48.226  8433  8433 I crash_reporter: type=1400 audit(0.0:217): avc: denied { getattr } for path="/proc/8412/status" dev="proc" ino=216902 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=file permissive=1
01-27 12:54:48.672   408   422 W ActivityManager: Activity pause timeout for ActivityRecord{f2233fb u0 com.amazingapps.sample.thingssample/.view.MainActivity t86 f}

通过chmod a+rw /sys/class/gpio/export至少我有所不同,可以打开和关闭引脚,并通过方法返回值进行验证,并检查/sys/class/gpio/gpio24的创建.

By chmod a+rw /sys/class/gpio/export at least I got a difference and could open and close the pin, verified by the method return value and also checking the creation of /sys/class/gpio/gpio24.

我正在尝试使用以下代码在Raspberry Pi 3上: https://github .com/fmatosqg/androidthings_ndk/tree/SO_question

I'm trying on a Raspberry Pi 3 with the following code: https://github.com/fmatosqg/androidthings_ndk/tree/SO_question

在另一种方法中,我尝试直接在Java中加载libperipheralman.so,以期对其函数进行调用(显然这是GPIO setValue()所在的位置),但是这一次我遇到了另一种问题,其中库因某些安全问题而被拒绝加载.请参阅Nougat文档,关于它们的原因是出于向后兼容性的考虑,不允许开发人员访问所有.so.

In another approach I tried loading libperipheralman.so directly in java in the hopes of making calls to its functions (apparently that's where GPIO setValue() lives), but this time I ran into a different kind of problem where a subset of the libraries were denied being loaded by some security problem. See Nougat documentation about them not allowing developers to access all .so because of back/future compatibility purposes.

我猜想,任何跳过使用Java VM/Dalvik的实现都可能使我更接近我的目标,即在.apk上获得不错的GPIO速度,但是我不知道是否有任何可行的方法可以在rpi3 + debian上使用.

I guess that any implementation that skips using Java VM/Dalvik has also the potential of gettting me closer to my goal, which is getting decent GPIO speed on an .apk, but I'm unaware if any of the approaches that work on rpi3 + debian can be used here.

推荐答案

每次要运行应用程序时都运行类似的命令(适用于第24针,请替换为您喜欢的针):

Run something like this everytime you're about to run the app (works for pin 24, replace with your preferred pin):

cd /sys/class/gpio
su root chmod a+w export
echo 24 > export
su root chmod a+w gpio24/direction
su root chmod a+w gpio24/value

ls gpio24/ -l

不幸的是,调用execl返回-1,而系统返回32256,因此无法替换此手动步骤.即使尝试system("/system/bin/date > /storage/self/primary/now ");也会给出32256.

Unfortunately calling execl returns -1 and system returns 32256, so there's no way to replace this manual step. Even by trying system("/system/bin/date > /storage/self/primary/now "); will give 32256.

然后将一个脚本侦听一个命名管道,并基于该脚本运行上面的代码.在使suchmod变得很容易使它易于运行之后,我编写了一个将写入同一管道的C代码.加300毫秒等待管道被读取,我将开始从apk内的C代码写入gpio23/方向和gpio/值.

Then put together a script that listens to a named pipe and based on that runs the above code. After struggling a bit with su and chmod to make it easy to run I put together a C code that would write to that same pipe. Add 300ms wait for the pipe to be read and I'd start writing to gpio23/direction and gpio/value from C code from inside apk.

Led发光了,一旦我优化了C代码以获得更紧密的循环,我就会发布一些速度基准测试.

Led is getting lit, and as soon as I optimize the C code for a tighter loop I'll post some speed benchmarking.

此处的完整解决方案 https://github.com/fmatosqg/androidthings_ndk/tree/SO_answer .看看README.md以获得指示.

Full solution here https://github.com/fmatosqg/androidthings_ndk/tree/SO_answer. Have a look at README.md for instructions.

为使其更好,我需要调试命名管道读取,因为有时我会读取错误的信息.并使脚本在启动时启动.

To make it better I'd need to debug the named pipe reading because sometimes I read the wrong info. And also make the script start at boot.

这篇关于如何在Android Things上绕过Java做GPIO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆