1. 程式人生 > >Android硬體訪問服務框架程式碼編寫

Android硬體訪問服務框架程式碼編寫

思路從最上層呼叫到底層編寫,流程如下: 1 實現與APP直接對接的操作硬體的介面,這個最簡單。 只需要實現AIDL檔案(Android Interface Define Language),其目的是讓安卓系統自動幫我們實現對應用JAVA介面檔案。

PS:可以搜尋原始碼中的例子比如:IVibrator.aidl,修改成如下程式碼:

package.android.os

Interface ILedService
{
        int ledctrl(int which, int status);
}

1 上傳AIDL檔案  將AIDL檔案上傳編譯之前,需要先編譯整個安卓原始碼(目前編譯4412開發板)。編譯完後上傳到目錄中,But,哪個目錄? 模仿其它AIDL檔案在哪個目錄,然後上傳到相應的目錄。 /android-5.0.2/frameworkds/base/core/java/android/os目錄下
2 修改/android-5.0.2/frameworkds/base/下的Android.mk檔案: 增加一行: core/java/android/os/ILedService.aidl\ 3 輸入mmm ./回車編譯當前目錄 4 編譯的結果放在/android-5.0.2/out/下 find -name "ILedService.java" 5 ILedService.java這個檔案介面如何使用。 先獲取Service,然後將其轉換為介面物件,然後呼叫這個介面物件的成員方法。 總結: 1 編寫ILedService.aidl檔案 ==>編譯生成ILedService.java檔案
2 app使用:ILedService   iLedService;                    iLedService = ILedService.Stub.asInterface(ServiceManager.getService("Led"))    呼叫:iLedService.ledctrl(0, 1); 所以使用者APP層呼叫iLedService介面,但是這個介面並不直接操作硬體,操作硬體的是LedService.java,下面描述這個LedService.java程式怎麼編寫。注意,這個LedService.java的作用是呼叫本地Native方法來操作硬體。 以下是原始碼:

 package com.android.server;
import android.os.ILedService;

public class LedService extends ILedService.Stub{
    private static final String TAG= "LedService";
    /* call native c function to access hardware */
    public int ledCtrl(int which, int status ) throw  //要實現ILedService內的介面就是這個。
    {
        return native_ledCtrl(which, status);
    }
   
    //in struct method call ledOpen()
    public LedService ()
    {
        native_ledOpen();
    }
    //declare native local methods.
    public static native  int native_ledCtrl(int which, int status );
    public static native  int native_ledOpen();
    public static native  void native_ledClose();
}

現在已經把LedService.java檔案寫好了,但是需要把它的這項服務告訴給SystemServer.java,故需要在SystemServer.java中新增這項服務,這裡稱之為addService. 方法如下:
Slog.i(TAG, "LedService"); 
ServiceManager.addService("Led",  new LedService()); //新增服務介面

總結:編寫好應用層介面的LedService.java檔案後,需要在SystemServer.java修改,新增服務:           ServiceManager.addService("Led", new LedService()); 以上工作完成後,後面就需要實現註冊Native本地方法(如下檔案),即編寫驅動的JNI封裝,供LedService.java呼叫。
com.android.Server.LedService.cpp:


#define LOG_TAG "LedService"

#include "jni.h"
#include "JNIHep.h"
#include "androd_runtime/AndroidRuntime.h"

namespace android
{
int register_android_server_LedService(JNIEnv *..)
{
    return jniRegisterNativeMethods(env,"comm/android/server/LedService",
       method_table, NELEM(method_table));
}

}

。。。(後面就是之前寫過的JNI程式)

還要修改onload.cpp,在裡面呼叫註冊方法,如下: register_android_server_LedService(env); 然後修改其Android.mk,並編譯。 編譯方法如下: $ mmm frameworks/base/services (由於有不同層的檔案有變化,找最上一層的) $ make snod (生成映象檔案) ==》生成out/target/product/tiny4412/system.img,後面只需要將這個映象檔案燒入開發板即可 $./gen-img.sh: 在此目錄下(work/android-5.0.2/下)生成映象檔案(與out/.../system.img是一樣的),此指令碼還可以生成userdata.img。 後面用minitool工作燒寫安卓system.img即可。