Android硬體訪問服務框架程式碼編寫
阿新 • • 發佈:2019-01-23
思路從最上層呼叫到底層編寫,流程如下:
1 實現與APP直接對接的操作硬體的介面,這個最簡單。
只需要實現AIDL檔案(Android Interface Define Language),其目的是讓安卓系統自動幫我們實現對應用JAVA介面檔案。
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方法來操作硬體。
以下是原始碼:
現在已經把LedService.java檔案寫好了,但是需要把它的這項服務告訴給SystemServer.java,故需要在SystemServer.java中新增這項服務,這裡稱之為addService. 方法如下:
總結:編寫好應用層介面的LedService.java檔案後,需要在SystemServer.java修改,新增服務: ServiceManager.addService("Led", new LedService()); 以上工作完成後,後面就需要實現註冊Native本地方法(如下檔案),即編寫驅動的JNI封裝,供LedService.java呼叫。
還要修改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即可。
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檔案
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即可。