Android驅動使用JNI調用

來源:互聯網
上載者:User

                                         Android驅動使用JNI調用

 

學習Android驅動是一個漫長的過程,當然你也可以說有了Linux裝置驅動開發經驗學習Android驅動是很簡單的,呵呵,的卻如此,畢竟Android核心是跑在linux核心上,Android的應用調用的其實是linux驅動。Android Application調用Linux驅動可以這麼說有兩種方法,也就是兩種處理的流程。
  Android應用程式層調用Linux驅動的方式:
  第一,通過在Android核心源碼(不是linux核心源碼)中添加HAL層、JNI層、開啟系統服務,這是一個比較複雜的過程,很多標準的裝置都採用這種方式設計,比如說wifi、gps、sensor等,這種調用過程看起來比較標準,但是如果作為第三方開發就會很麻煩,HAL層、JNI層,系統服務層,每層都需要編譯Android核心源碼,這樣就會延長了產品的開發週期;第二,通過配置NDK環境,在NDK環境中直接編寫JNI層,然後在Android應用程式層中添加類,載入JNI庫即可調用裝置的驅動。
  現在我們以Tiny210上的LED驅動作為例子講解如何使用NDK環境編寫JNI庫來調用裝置的驅動程式。
  一、首先是編寫linux驅動程式,:
1、源碼:linux-2.6.36-android\drivers\char\tiny210_leds.c
2、修改目前的目錄(linux-2.6.36-android\drivers\char)的kconfig,添加如下內容:
config TINY210_LEDS
 tristate "LED Support for Tiny210 GPIO LEDs"
 depends on CPU  S5PV210

 default y
 help
   This option enables support for LEDs connected to GPIO lines
   on Tiny210 boards.
3、修改目前的目錄(linux-2.6.36-android\drivers\char)下的makefile檔案,添加如下內容:
obj-$(CONFIG_TINY210_LEDS) += tiny210_leds.o
4、到源碼目錄執行make menuconfig 配置LED驅動編譯進核心,系統起來就載入驅動
5、執行 make 產生zImage鏡像檔案
二、 重新使用剛剛編譯好的zImage燒寫Android系統,系統起來以後通過adb查看Android系統載入的驅動程式
#ls /dev 
可以看到系統載入的驅動,(leds)
修改init.rc載入的驅動的讀寫權限
chmod 0666 /dev/leds
這樣JNI層才可以開啟這個裝置
三、編寫JNI檔案
在android工程目錄下建立檔案jni,然後添加檔案ledjni.c,內容如下:
#include <string.h>
#include <jni.h>
#include <fcntl.h>
#define DEV_NAME "/dev/leds"
jstring
Java_com_hellojnipwzh_HardwareControlClass_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}
jint
Java_com_hellojnipwzh_HardwareControlClass_Init(JNIEnv *env,
          jobject thiz)
{
 int fd=open(DEV_NAME,O_RDWR);
 return fd;
}
jint
Java_com_hellojnipwzh_HardwareControlClass_IOCTLLED(JNIEnv *env,
          jobject thiz,
          jint ledid,
          jint controlcode,
          jint fd)
{
 int CTLCODE = controlcode;
 ioctl(fd,controlcode,ledid);
 return 0;
}
說明:“Java_com_hellojnipwzh_HardwareControlClass_IOCTLLED”,在工程中添加JNI類時,使用com.hellojnipwzh作為packets name,HardwareControlClass這個作為class name  ,IOCTLLED(int id,int code,int fd)作為調用的介面函數,類成員。

添加指令碼Android.mk,內容如下:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ledjni
LOCAL_SRC_FILES := ledjni.c

include $(BUILD_SHARED_LIBRARY)

使用Cygwin工具,配置好NDK環境,添加NDK環境到系統變數中,然後進到jni目錄,進行
#ndk-build
這樣就會在android工程的libs目錄下的armeabi目錄下產生ledjni.so
這樣JNI庫已經完成了,接下來就是添加類來調用JNI庫
四、JNI類
在Android工程中添加一個類,包名:com.hellojnipwzh 類名:HardwareControlClass,具體內容如下:
package com.hellojnipwzh;

import android.util.Log;

public class HardwareControlClass {
 
 static public native String stringFromJNI();
 static public native int Init();
 static public native int IOCTLLED(int ledID, int ledState ,int fd);
 
 static {
     try {
      System.loadLibrary("ledjni");
     } catch (UnsatisfiedLinkError e) {
         Log.d("HardwareControler", "HardwareControler ibrary not found!");
     }
 }
}
五、接下來就是在Android應用程式層代碼中通過類來訪問驅動了
package com.hellojnipwzh;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class HelloJniPwzh extends Activity {

 int fd = -1;
 TextView tv;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_hello_jni_pwzh);

  
  
  fd = HardwareControlClass.Init();
  if (-1 == fd)
   Log.d("JNI", "open device error!");
   
  tv = (TextView)findViewById(R.id.tvid);
  String tstr = "ssss";
  tstr = HardwareControlClass.stringFromJNI();
  tv.setText(tstr);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_hello_jni_pwzh, menu);
  return true;
 }
 
 public void onclickLedOn1(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(1, 1, fd);
 }
 public void onclickLedOff1(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(1, 0, fd);
 }
 
 public void onclickLedOn2(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(2, 1, fd);
 }
 public void onclickLedOff2(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(2, 0, fd);
 }
 
 public void onclickLedOn3(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(3, 1, fd);
 }
 public void onclickLedOff3(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(3, 0, fd);
 }
 
 public void onclickLedOn4(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(4, 1, fd);
 }
 public void onclickLedOff4(View v)
 {
  if (fd != -1)
   HardwareControlClass.IOCTLLED(4, 0, fd);
 }

}
至此JNI的調用過程也已經完成,接下來就是將Android軟體安裝到Tiny210上,然後點擊下按鈕,你就會發現你可以通過Android軟體來控制Linux驅動程式了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.