레이블이 root인 게시물을 표시합니다. 모든 게시물 표시
레이블이 root인 게시물을 표시합니다. 모든 게시물 표시

2015년 6월 3일 수요일

How to install GAppsInstaller(Lollipop) on ODROID-XU3 CM version

Download GAppsInstaller for Lollipop.
http://dn.odroid.com/GAPPS/GAppsInstaller_lollipop.apk



Install GAppsInstaller.




But failed.


Get root permission.
Click Build number many times.


Now find Developer options.


Root access.



go back Setting and enter Privacy.


Privacy Guard.
Check 'Enabled by default and Gapps Installer item'


Now Can install.



Reboot and go 'Play Store'.



2015년 4월 10일 금요일

WiringPi on ODROID-C1(Android)

WiringPi on ODROID-C1(Android)



ODROID-C1 Ubuntu에서 Raspberry Pi에서 사용되는 WiringPi를 사용할 수 있도록 porting 하였습니다.

http://odroid.com/dokuwiki/doku.php?id=en:c1_tinkering

wiringPi를 사용한 example-led 예제를 Android 에서도 사용할 수 있도록 작업을 해 보았습니다.

먼저 소스를 다운 받습니다.

git clone https://github.com/codewalkerster/example-led

다운 받은 소스를 eclipse에서 import 시킵니다.


그리고 NDK를 이용하여 wiringPi를 build합니다.

$ cd example-led/jni
$ ndk-build
Android NDK: WARNING: APP_PLATFORM android-16 is larger than android:minSdkVersion 7 in /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/AndroidManifest.xml  
[armeabi] Compile thumb  : wiringPi <= wiringPi.c
/media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c:147:0: warning: "PAGE_SIZE" redefined [enabled by default]
 #define PAGE_SIZE   (4*1024)
 ^
In file included from /home/codewalker/projects/android-ndk-r10d/platforms/android-21/arch-arm/usr/include/signal.h:34:0,
                 from /home/codewalker/projects/android-ndk-r10d/platforms/android-21/arch-arm/usr/include/poll.h:34,
                 from /media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c:59:
/home/codewalker/projects/android-ndk-r10d/platforms/android-21/arch-arm/usr/include/limits.h:119:0: note: this is the location of the previous definition
 #define PAGE_SIZE 4096
 ^
/media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c: In function 'interruptHandler':
/media/codewalker/92fc070a-3bc1-43e0-af27-03d08ba9dd3e/home/codewalker/workspace/xxxx/example-led/jni/wiringPi/wiringPi.c:1865:7: warning: return makes pointer from integer without a cast [enabled by default]
       return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
       ^
[armeabi] Compile thumb  : wiringPi <= wiringShift.c
[armeabi] Compile thumb  : wiringPi <= piHiPri.c
[armeabi] Compile thumb  : wiringPi <= piThread.c
[armeabi] Compile thumb  : wiringPi <= wiringPiSPI.c
[armeabi] Compile thumb  : wiringPi <= wiringPiI2C.c
[armeabi] Compile thumb  : wiringPi <= softPwm.c
[armeabi] Compile thumb  : wiringPi <= softTone.c
[armeabi] Compile thumb  : wiringPi <= mcp23008.c
[armeabi] Compile thumb  : wiringPi <= mcp23016.c
[armeabi] Compile thumb  : wiringPi <= mcp23017.c
[armeabi] Compile thumb  : wiringPi <= mcp23s08.c
[armeabi] Compile thumb  : wiringPi <= mcp23s17.c
[armeabi] Compile thumb  : wiringPi <= sr595.c
[armeabi] Compile thumb  : wiringPi <= pcf8574.c
[armeabi] Compile thumb  : wiringPi <= pcf8591.c
[armeabi] Compile thumb  : wiringPi <= mcp3002.c
[armeabi] Compile thumb  : wiringPi <= mcp3004.c
[armeabi] Compile thumb  : wiringPi <= mcp4802.c
[armeabi] Compile thumb  : wiringPi <= mcp3422.c
[armeabi] Compile thumb  : wiringPi <= max31855.c
[armeabi] Compile thumb  : wiringPi <= max5322.c
[armeabi] Compile thumb  : wiringPi <= sn3218.c
[armeabi] SharedLibrary  : libwiringPi.so
[armeabi] Install        : libwiringPi.so => libs/armeabi/libwiringPi.so
[armeabi] Compile thumb  : wiringPiDev <= ds1302.c
[armeabi] Compile thumb  : wiringPiDev <= maxdetect.c
[armeabi] Compile thumb  : wiringPiDev <= piNes.c
[armeabi] Compile thumb  : wiringPiDev <= gertboard.c
[armeabi] Compile thumb  : wiringPiDev <= piFace.c
[armeabi] Compile thumb  : wiringPiDev <= lcd128x64.c
[armeabi] Compile thumb  : wiringPiDev <= lcd.c
[armeabi] Compile thumb  : wiringPiDev <= piGlow.c
[armeabi] SharedLibrary  : libwiringPiDev.so
[armeabi] Install        : libwiringPiDev.so => libs/armeabi/libwiringPiDev.so
[armeabi] Compile thumb  : wpi_android <= wpi_android.c
[armeabi] SharedLibrary  : libwpi_android.so
[armeabi] Install        : libwpi_android.so => libs/armeabi/libwpi_android.so 



jni/Android.mk 에 libwingPi.so와 libwingPiDev.so 빌드하도록 추가 하였습니다.

include $(CLEAR_VARS)
LOCAL_C_INCLUDES += \
    $(NDK_PATH)/platforms/android-21/arch-arm/usr/include \
    $(LOCAL_PATH)/wiringPi

LOCAL_MODULE    := wiringPi
LOCAL_SRC_FILES := \
    wiringPi/wiringPi.c \
    wiringPi/wiringShift.c \
    wiringPi/piHiPri.c \
    wiringPi/piThread.c \
    wiringPi/wiringPiSPI.c \
    wiringPi/wiringPiI2C.c \
    wiringPi/softPwm.c \
    wiringPi/softTone.c \
    wiringPi/mcp23008.c \
    wiringPi/mcp23016.c \
    wiringPi/mcp23017.c \
    wiringPi/mcp23s08.c \
    wiringPi/mcp23s17.c \
    wiringPi/sr595.c \
    wiringPi/pcf8574.c \
    wiringPi/pcf8591.c \
    wiringPi/mcp3002.c \
    wiringPi/mcp3004.c \
    wiringPi/mcp4802.c \
    wiringPi/mcp3422.c \
    wiringPi/max31855.c \
    wiringPi/max5322.c \
    wiringPi/sn3218.c

LOCAL_CFLAGS    += -UNDEBUG -DANDROID

LOCAL_LDLIBS    := -ldl -llog
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_C_INCLUDES += \
    $(NDK_PATH)/platforms/android-21/arch-arm/usr/include \
    $(LOCAL_PATH)/wiringPi

LOCAL_MODULE    := wiringPiDev
LOCAL_SRC_FILES := \
    devLib/ds1302.c \
    devLib/maxdetect.c \
    devLib/piNes.c \
    devLib/gertboard.c \
    devLib/piFace.c \
    devLib/lcd128x64.c \
    devLib/lcd.c \
    devLib/piGlow.c

LOCAL_SHARED_LIBRARIES := libwiringPi

LOCAL_CFLAGS    += -UNDEBUG
include $(BUILD_SHARED_LIBRARY)

그리고 wirinPi에서 사용해야 하는 function을 jni 형식으로 만듭니다.

jint Java_com_hardkernel_wiringpi_MainActivity_analogRead(JNIEnv* env, jobject obj, jint port) {
    return analogRead(port);
}

void Java_com_hardkernel_wiringpi_MainActivity_digitalWrite(JNIEnv* env, jobject obj, jint port, jint onoff) {
    digitalWrite(port, onoff);
}

int Java_com_hardkernel_wiringpi_MainActivity_wiringPiSetupSys(JNIEnv* env, jobject obj) {
    wiringPiSetupSys();
    return 0;
}

사용한 GPIO를 선언합니다.

    private final int ledPorts[] = {
        97, // GPIOX.BIT0(#97)
        108, // GPIOX.BIT11(#108)
        100, // GPIOX.BIT3(#100)
        101, // GPIOX.BIT4(#101)
        105, // GPIOX.BIT8(#105)
        106, // GPIOX.BIT9(#106)
        107, // GPIOX.BIT10(#107)
        115,  // GPIOX.BIT18(#115)
        116,  // GPIOX.BIT19(#116)
        88,  // GPIOY.BIT8(#88)
        83,  // GPIOY.BIT3(#83)
        87,  // GPIOY.BIT7(#87)
        104,  // GPIOX.BIT7(#104)
        102,  // GPIOX.BIT5(#102)
        103,  // GPIOX.BIT6(#103)
        117, // GPIOX.BIT20(#117)
        99, // GPIOX.BIT2(#99)
        118, // GPIOX.BIT21(#118)
        98, // GPIOX.BIT1(#98)
    };

MainActivity에 jni function들을 선언합니다.

    public native int wiringPiSetupSys();
    public native int analogRead(int port);
    public native void digitalWrite(int port, int onoff);

    static {
        System.loadLibrary("wpi_android");
    }

/sys/class/gpio/export를 이용하여 GPIO sysfs 노드를 만듭니다.
sysfs 방식은 pinMode()를 사용할 수 없기 때문에 directionout으로 설정 합니다.
그리고 value, direction의 접근 권한을 바꿉니다.

    boolean exportGPIO() {
        try {
            DataOutputStream os = new DataOutputStream(mProcess.getOutputStream());
            for (int port: ledPorts) {
                os.writeBytes("echo " +  port + " > /sys/class/gpio/export\n");
                os.writeBytes("chmod 666 /sys/class/gpio/gpio" + port + "/direction\n");
                os.writeBytes("echo out > /sys/class/gpio/gpio" + port + "/direction\n");
                os.writeBytes("chmod 666 /sys/class/gpio/gpio" + port + "/value\n");
            }
            os.flush();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            return false;
        }

        return true;
    }

wiringPi의 "/dev/mem"을 open 하여 mmap을 사용하는 방식으로 만들려고 하였으니 "/dev/mem"은 root가 아니면 접근을 제한하도록 되어 있어서 불가능합니다.
jni의 library에는 root 권한을 줄 방법이 없습니다.

그래서 wiringPiSetupSys()를 호출 하여 wiringPi library를 초기화 합니다.


주기적으로 update()를 호출 하도록 만들고 UI와 LED를 control 합니다.

    public void update() {
        int i = 0;
        int adcValue = 0;
        int ledPos = 0;
        if ((adcValue = analogRead (PORT_ADC1)) > 0) {
            ledPos = (adcValue * ledPorts.length * 1000) / 1024;
            ledPos = (ledPorts.length - (ledPos / 1000));
            mADC.setProgress(adcValue);
        } else
            ledPos = 0;

        for (i = 0; i < ledPorts.length; i++) {
            digitalWrite (ledPorts[i], 0);
            mLeds.get(i).setChecked(false);
        }

        for (i = 0; i < ledPos; i++) {
            digitalWrite (ledPorts[i], 1);
            mLeds.get(i).setChecked(true);
        }

        if (!mStop)
            handler.postDelayed(runnable, 100);
    }