简体   繁体   English

如何在Android上做GPIO绕过Java

[英]How to do GPIO on Android Things bypassing Java

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. 我一直在尝试使用NDK在Raspberry Pi上使用Android东西访问GPIO,但在尝试了几种方法后,我总会发现某种安全墙阻止我访问它。

The motivation is the sluggish speed I'm getting from GPIO using the Java API. 我的动机是使用Java API从GPIO获得的缓慢速度。 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 . 作为基本参考,我能够以大约2KHz的频率打开和关闭它,这恰好是这个列表中最差的。 See also What is Android Things Raspberry Pi GPIO max frequency? 另请参阅什么是Android Things Raspberry Pi GPIO最大频率? , where so far there's no answer and where I added a comment about java speed. 到目前为止还没有答案,我添加了关于java速度的评论。 In fact this work was motivated by the results I got when checking for that question. 事实上,这项工作的动机是我在检查这个问题时得到的结果。

The best approach so far is trying something similar to what would take for sysfs under Debian. 到目前为止,最好的方法是尝试类似于Debian下sysfs所需的方法。 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: 在这种程度上,代码似乎公平,但在以root身份运行后,将应用程序安装为系统应用程序(通过将其移动到/ system / app)并在/sys/class/gpio//sys/class/gpio/gpio24/下chmod a + rw几个不同的东西/sys/class/gpio/gpio24/以及/dev/gpiomem这就是我得到的:

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}

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 . 通过chmod a+rw /sys/class/gpio/export至少我得到了一个区别,可以打开和关闭引脚,通过方法返回值进行验证,并检查/sys/class/gpio/gpio24

I'm trying on a Raspberry Pi 3 with the following code: https://github.com/fmatosqg/androidthings_ndk/tree/SO_question 我正在使用以下代码尝试使用Raspberry Pi 3: https//github.com/fmatosqg/androidthings_ndk/tree/SO_question

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. 在另一种方法中,我尝试直接在java中加载libperipheralman.so ,希望调用它的函数(显然这就是GPIO setValue()所在的位置),但这次我遇到了一个不同类型的问题,其中一个库的子集是否认被某些安全问题所困扰。 See Nougat documentation about them not allowing developers to access all .so because of back/future compatibility purposes. 请参阅Nougat文档,了解它们不允许开发人员访问所有.so,因为后面/将来的兼容性目的。

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. 我想任何使用Java VM / Dalvik跳过的实现也有可能使我更接近我的目标,即在.apk上获得合适的GPIO速度,但我不知道是否有任何一种方法可用于rpi3 + debian可以在这里使用。

EDITED: 编辑:

Run something like this everytime you're about to run the app (works for pin 24, replace with your preferred pin): 每次你要运行应用程序时运行这样的东西(适用于引脚24,用你喜欢的引脚替换):

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

Unfortunately calling execl returns -1 and system returns 32256, so there's no way to replace this manual step. 不幸的是,调用execl返回-1并且系统返回32256,因此无法替换此手动步骤。 Even by trying system("/system/bin/date > /storage/self/primary/now "); 即使通过尝试system("/system/bin/date > /storage/self/primary/now "); will give 32256. 将给出32256。

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. 在使用suchmod进行了一些努力以使其易于运行之后,我将一个C代码放在一起写入同一个管道。 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. 添加300ms等待管道读取,我开始写入gpio23 / direction和gpio / value来自apk内部的C代码。

Led is getting lit, and as soon as I optimize the C code for a tighter loop I'll post some speed benchmarking. Led正在点亮,一旦我优化了C代码以获得更紧密的循环,我就会发布一些速度基准测试。

Full solution here https://github.com/fmatosqg/androidthings_ndk/tree/SO_answer . 完整解决方案https://github.com/fmatosqg/androidthings_ndk/tree/SO_answer Have a look at README.md for instructions. 有关说明,请查看README.md。

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. 并且还使脚本在启动时启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM