android開發:振動器系統

一.振動器系統結構和移植內容

振動器負責控制引用電話的震動功能,Android中的振動器系統是一個專供這方面功能的小系統,提供根據時間的振動功能。

振動器系統包含瞭驅動程序,硬件抽象層,JNI部分,java框架類等幾個部分,也向java應用程序層提供瞭簡單的API作為平臺接口。

 

二.振動器部分的結構

 Android振動器系統自下而上包含瞭驅動程序,振動器系統硬件抽象層,振動器系統java框架類,java框架中振動器系統使用等幾個部分。

 

  自下而上,Android的振動器系統分成瞭以下部分。

1.      驅動程序:特定硬件平臺振動器的驅動程序,通常基於Android的Timed Output驅動框架實現

2.      硬件抽象層:振動器系統的硬件抽象層在Android中已經具有默認實現,代碼路徑:

Hardware/libhardwar_legacy/vibrator/vibrator.c

振動器的硬件抽象層通常並不重新實現,是libhardware_legacy.so的一部分。

 

3.      JNI部分

這個類是振動器的JNI部分,通過調用硬件抽象層向上提供接口。

 

4.      Java部分VibratorService.java通過調用,VibratorService JNI 來實現 com.android.server包中的VibrattorService類。這個類不是平臺的API,被Android 系統Java框架中的一小部分的調用.Vibrator.java文件實現瞭android.os包中的Vibrator類,這是向java層提供的API

 

三.移植方法

針對特定的硬件平臺,振動器系統的移植有兩種方法。

第一種方法:由於已經具有硬件抽象層,振動器系統的移植隻需要實現驅動程序即可。這個驅動程序需要給予Android內核中的Timed Output驅動框架。

第二種方法:根據自己實現的驅動程序,重新實現振動器的硬件抽象層定義接口,由於振動器硬件抽象層的接口非常簡單,因此這種實現方式也不會很復雜。

 

四.移植與調試的要點

1. 驅動程序

  Vibrator的驅動程序隻需要實現振動的接口即可,這是一個輸出設備,需要接受振動時間作為參數。由於比較簡單,因此Vibrator驅動程序可以使用多種方式來實現。

   在Android中,推薦基於Android內核定義TimedOutput驅動程序框架來實現Vibrator的驅動程序。

  Timed Output的含義為定時輸出,用於定時發出某個輸出。實際上,這種驅動程序依然是基於sys文件系統來完成的。

   Driver/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設備,其實現的TimedOutput驅動程序的名稱應該為“vibrator”。因此Vibrator設備在sys文件系統中的方法如下:

#echo”10000”>/sys/class/timed_output/vibrator/enable

#cat/sys/class/timed_output/vibrator/enable

3290

#echo”0”>/sys/class/timed_output/vibrator/enable

對於enable文件,“寫”表示使能指定的時間,“讀”表示獲取剩餘時間。

 

2.硬件抽象層的接口

  Vibrator硬件抽象層的接口在hardware/libhardware_legacy/include/hardware_legacy/目錄的vibrator.h文件中定義:

  int vibrator_on(int timeout_ms);

  int vibrator_off();

  vibrator.h文件中定義兩個接口,分別表示振動和關閉,振動開始以毫秒作為時間單位。

 

3. 標準硬件抽象層的實現

  Vibrator硬件抽象層具有標準的實現。在hardware/libhardware_legacy/vibrator/目錄的vibrator.c中。

   其中實現的核心內容為sendit()函數,這個函數的內容如下:

 

 

[java] <span style="font-size:16px;"> #define THE_DEVICE “/sys/class/timed_output/vibrator/enable” 
   static int sendit(int timeout_ms) 
   { 
      int nwr,ret,fd; 
      char value[20]; 
      ifdef QEMU_HARDWARE 
      if (qemu_check()){ 
      return qemu_control_command(“vibrator:%d,timeout_ms); 
      } 
      #endif 
      fd=open(THE_DEVICE,O_RDWR); 
      if(fd<0) return errno; 
      nwr=sprint(value,”%d\n”,timeout_ms); 
      ret=write(fd,value,nwr); 
      close(fd); 
      return (rnt == nwr) ? 0 : -1; 

</span> 
<span style="font-size:16px;"> #define THE_DEVICE “/sys/class/timed_output/vibrator/enable”
   static int sendit(int timeout_ms)
   {
      int nwr,ret,fd;
      char value[20];
      ifdef QEMU_HARDWARE
      if (qemu_check()){
      return qemu_control_command(“vibrator:%d,timeout_ms);
      }
      #endif
      fd=open(THE_DEVICE,O_RDWR);
      if(fd<0) return errno;
      nwr=sprint(value,”%d\n”,timeout_ms);
      ret=write(fd,value,nwr);
      close(fd);
      return (rnt == nwr) ? 0 : -1;
}
</span>

 

Sendit()函數負責根據時間“振動”,在真實的硬件中,通過sys文件系統的文件進行控制;如果是模擬器環境則通過QEMU發送命令。

Vibrator_on()調用sendit()以時間作為參數,vibrator_on()調用sendit()以0作為參數。

 

摘自 北京大學-Google Android實驗室

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *