Android NDK GPIO操做(pcduino 裝Android系統)

開發工具: Eclipse
開發語言: Java和c++
     Pcduino跑Android系統讓我興奮了很長時間,也由此幻想了不少有趣的應用。例如 結合Yeelink作遠程加電控制;結合微信開放接口與傳感器向好友推送信息等等。 固然這些有趣的應用都離不開PCDUINO硬件的操做。那麼在Android系統下怎麼來操做硬件呢?我想大概有如下幾種方式:


一、利用Arduino 庫本身寫c++程序而後編譯成可執行文件,而後把可執行文件拷到PCDUINO中,添加權限,在模擬中端裏運行可執行文件。
     優勢:Arduino庫函數完善,很是容易操做。
     缺點:貌似和Android開發的應用不能完美的結合。

二、利用Android 的Jni編程,直接驅動GPIO。
     優勢:開發工具簡單,利用Eclipse進行交叉編譯,同時編譯Java和c++代碼。而且把硬件操做函數生成.so文件直接打包APK中。

     下面咱們利用ANDROID NDK來開發一個簡單實例: "光電開關控制UI上的燈泡亮滅"

      第一步:開發環境的搭建
                  一、安裝Eclipse
                  二、安裝ADT-v20插件(該版本已經直接支持Native編程)
                  三、安裝CDT(編譯c++代碼)
                  三、安裝android-ndk-r8e(該版本支持Windows,不用在Cygwin下編譯了)
       按照這種模式搭建的開發環境用起來很是上手,java和c++程序直接交叉編譯,而後打包生成APK.
      第二步:實例演練
                  一、新建Android 工程HelloJni,編寫Java代碼以下(定義本地函數)
                 public class MainActivity extends Activity 
            {        
                  @Override
                  protected void onCreate(Bundle savedInstanceState) 
        
              {
                super.onCreate(savedInstanceState);
                setTitle(getHelloJniData());
        
               }

                //c++中要實現的函數接口
                 public native String getHelloJniData();    //從本地函數得到字符串
                 public native void OpenLed();                //打開LED燈,本例子對應GPIO3
                 public native void CloseLed();                //關閉LED燈
                 public native int  ReadGpioState(int i);    //讀取某個GPIO的狀態,而後返回給Java層

                 //庫載入代碼
                 static
                 {
                     System.loadLibrary("Hellojni");          //Hellojni本地SO庫
                  }
             }
                    二、實現本地c++代碼
            (此處注意能夠利用 javah 生成頭文件,也能夠本身按照Jni規則寫)


             #define GPIO_MODE_DIR "/sys/devices/virtual/misc/gpio/mode/"
             #define GPIO_PIN_DIR "/sys/devices/virtual/misc/gpio/pin/"
             #define GPIO_IF_PREFIX "gpio"



            JNIEXPORT jstring JNICALL Java_com_hellojni_MainActivity_getHelloJniData (JNIEnv * env, jobject obj )
             
             {
                  return (*env)->NewStringUTF(env, "hello jni");
             }


              JNIEXPORT void JNICALL Java_com_hellojni_MainActivity_OpenLed (JNIEnv * env, jobject obj)   //打開LED
           {




                __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"OPEN- LED");


                memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_MODE_DIR, GPIO_IF_PREFIX, 3);    //此處對應地址/sys/devices/virtual/misc/gpio/mode/gpio3 設置爲輸出
                fd = open(path, O_RDWR);
                write(fd,"1",1);
                close(fd);


                 memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, 3);         //此處對應地址/sys/devices/virtual/misc/gpio/pin/gpio3 設置爲高定平
                fd = open(path, O_RDWR);
                write(fd,"1",1);
                close(fd);
        }


       JNIEXPORT void JNICALL Java_com_hellojni_MainActivity_CloseLed(JNIEnv * env, jobject obj) //關閉LED
               
       {
              __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"CLOSE LED");
                memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_MODE_DIR, GPIO_IF_PREFIX, 3);
                fd = open(path, O_RDWR);
                write(fd,"1",1);
                close(fd);


                memset(path, 0, sizeof(path));
                sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, 3);
                fd = open(path, O_RDWR);
                write(fd,"0",1);
                close(fd);
       }



       JNIEXPORT jint JNICALL Java_com_hellojni_MainActivity_ReadGpioState (JNIEnv *env, jobject obj,jint i) //讀取某個IO口的狀態
            {
                   char buf[4];
                    int ret = -1;
                    int fd = -1;
                    int state;


                    memset((void *)buf, 0, sizeof(buf));


                    memset(path, 0, sizeof(path));
                    sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, i);
                    fd = open(path, O_RDWR);
                    ret = read(fd, buf, sizeof(buf));


                    ret = buf[0] - '0';
                           switch( ret )
                           {
                               case 0:
                                       state=0;
                                    //   __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"LOW");    返回LOG調試信息
                                         break;
                               case 1:
                                       state=1;
                                    //   __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"HIGHT");
                                     break;
                               default:
                                       state=-1;
                                   ret = -1;
                                   break;
                           }
                      close(fd);
                             //  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"READ GPIO STATE");
            return state;
        }



                  三、到這裏關鍵代碼就都準備好了,能夠直接在Java層調用這些接口函數操做IO了。下面最後再配置一下Eclipse交叉編譯環境。
                         
                       右擊HelloJni的工程屬性,彈出 窗口,選Builders --->New---NDK_Builder。
php

 




 




 




 




 




到此開發環境搭建完畢!具體的細節哪裏有問題,能夠問度娘哦!!!java


工程文件見附件!!!android


感謝Lucifer㊣(1094294)大神的指導!!!c++




 hellojni.rar (985.58 KB, 下載次數: 22) 




web

相關文章
相關標籤/搜索