Android震動系統結構 移植與調試的要點

振動器負責控制引動德律風的振動功能,Android中的振動器系統是一個專供這方面功能的小系統,提供根據時間振動的功能。
振動器系統包含了驅動軌範、硬件抽象層、JNI部門、Java框架類等幾個部門,也向Java應用軌範層提供了簡單的API作爲平臺接口。Android振動器系統的基本條理結構如圖23-1所示。

▲圖23-1 Android振動器系統的基本條理結構
1 、振動器部門的結構
Android振動器系統自下而上包含了驅動軌範、振動器系統硬件抽象層、振動器系統Java框架類、Java框架中振動器系統使用等幾個部門,其結構如圖23-2所示。


▲圖23-2 Android振動器系統的結構
自下而上,Android的振動器系統分成了以下部門。
(1)驅動軌範:特定硬件平臺振動器的驅動軌範,通常基於Android的Timed Output驅動框架實現
(2)硬件抽象層
光系統硬件抽象層接口路徑爲:hardware/libhardware_legacy/include/hardware_legacy/ vibrator.h
振動器系統的硬件抽象層在Android中已經具有默認實現,代碼路徑:
hardware/libhardware_legacy/vibrator/vibrator.c
振動器的硬件抽象層通常其實不需要重新實現,是libhardware_legacy.so的一部門。
(3)JNI部門
代碼路徑:frameworks/base/services/jni/com_android_server_VibratorService.cpp
這個類是振動器的JNI部門,通過挪用硬件抽象層向上層提供接口。
(4)Java部門
代碼路徑:
frameworks/base/services/java/com/android/server/VibratorService.java
frameworks/base/core/java/android/os/Vibrator.java
VibratorService.java通過挪用,VibratorService JNI來實現com.android.server包中的VibratorService類。這個類不是平臺的API,被Android系統Java框架中的一小部門挪用。
Vibrator.java文件實現了android.os包中的Vibrator類,這是向Java層提供的API。

2 、移植內容
針對特定的硬件平臺,振動器系統的移植有兩種體例。
第一種體例(通常情況):由於已經具有硬件抽象層,振動器系統的移植只需要實現驅動軌範即可。這個驅動軌範需要基於Android內核中的Timed Output驅動框架。
第二種體例:根據自己實現的驅動軌範,重新實現振動器的硬件抽象層界說接口(需要在libhardware_legacy.so庫中),由於振動器硬件抽象層的接口很是簡單,因此這種實現體例也不會很複雜。
1、驅動軌範
Vibrator的驅動軌範只需要實現振動的接口即可,這是一個輸出設備,需要接受振動時間作爲參數。由於鬥勁簡單,因此Vibrator的驅動軌範可使用多種體例來實現。
在Android中,推薦基於Android內核界說Timed Output驅動軌範框架來實現Vibrator的驅動軌範。
Timed Output的含義爲按時輸出,用於按時發出某個輸出。實際上,這種驅動軌範依然是基於sys文件系統來完成的。
drivers/staging/android/目錄timed_output.h中界說timed_output_dev結構體,其中包含enable和get_time這兩個函數指針,實現結構體後,使用timed_output_dev_register和timed_output_dev_unregister函數註冊和註銷即可。
Timed Output驅動軌範框架將爲每個設備在/sys/class/timed_output/目錄中建立一個子目錄,設備子目錄中的enable文件就是設備的控制文件。讀enable文件暗示獲得剩餘時間,寫這個文件暗示根據時間振動。
Timed Output驅動的設備調試,通過sys文件系統即可。
對Vibrator設備,其實現的Timed Output驅動軌範的名稱應該爲“vibrator”。因此Vibrator設備在sys文件系統中的體例如下所示:
# echo"10000">/sys/class/timed_output//enable
# cat/sys/class/timed_output//enable
3290
# echo"0">/sys/class/timed_output//enable
對enable文件,“寫”暗示使能指定的時間,“讀”暗示獲取剩餘時間。
2 、硬件抽象層的內容
1.硬件抽象層的接口
Vibrator硬件抽象層的接口在hardware/libhardware_legacy/include/hardware_legacy/目錄的vibrator.h文件中界說:
int vibrator_on(int timeout_ms); // 開始振動
int vibrator_off; // 關閉振動
vibrator.h文件中界說兩個接口,別離暗示振動和關閉,振動開始以毫秒(ms)作爲時間單元。

提示:Timed Output類型驅動自己有獲得剩餘時間的能力(讀enable文件),可是在Android Vibrator硬件抽象層以上的各層接口都沒有使用這個功能。
2.尺度硬件抽象層的實現
Vibrator硬件抽象層具有尺度的實現,在hardware/libhardware_legacy/vibrator/目錄的vibrator.c中。
其中實現的核心內容爲sendit函數,這個函數的內容如下所示:
#define THE_DEVICE"/sys/class/timed_output/vibrator/enable"
staticintsendit(inttimeout_ms)
{
intnwr, ret, fd;
char value[20];
#ifdef QEMU_HARDWARE//使用QEMU的情況
if(qemu_check) {
return qemu_control_command("vibrator:%d", timeout_ms );
}
#endif
fd=open(THE_DEVICE, O_RDWR);//讀取sys文件系統中的內容
if(fd<0) return errno;
nwr=sprintf(value,"%d\n", timeout_ms);
ret=write(fd, value, nwr);
close(fd);
return (ret==nwr) ?0:-1;
}
sendit函數負責根據時間“振動”:在真實的硬件中,通過sys文件系統的文件進行控制;如果是模擬器環境則通過QEMU發送命令。
vibrator_on挪用sendit以時間作爲參數,vibrator_on挪用sendit以0作爲參數。
3、上層的情況和注意事項
frameworks/base/services/jni/目錄中的com_android_server_VibratorService.cpp文件是Vibrator硬件抽象層的挪用者,它同時也向Java提供JNI支持。
其中,爲JNI界說的體例列表如下所示:
static JNINativeMethod method_table[]={
{"vibratorOn","(J)V", (void*)vibratorOn },//振動器開
{"vibratorOff","V", (void*)vibratorOff }//振動器關
};
intregister_android_server_VibratorService(JNIEnv*env) {
return jniRegisterNativeMethods(env,"com/android/server/VibratorService",
method_table, NELEM(method_table));
}
vibratorOn和vibratorOff這兩個函數的實現別離如下所示:
static void vibratorOn(JNIEnv*env, jobject clazz, jlong timeout_ms){
vibrator_on(timeout_ms);
}
static void vibratorOff(JNIEnv*env, jobject clazz){
vibrator_off;
}
frameworks/base/services/java/com/android/server/目錄中的VibratorService.java通過挪用VibratorService JNI來實現com.android.server包中的VibratorService類。
frameworks/base/core/java/android/os/目錄中的Vibrator.java文件實現了android.os包中的Vibrator類。它通過挪用vibrator的Java服務來實現(獲得名稱爲vibrator的服務),配合同目錄中的IVibratorService.aidl文件嚮應用軌範層提供Vibrator的相關API。




發佈了21 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章