1. 程式人生 > >Android震動vibrator(馬達)--系統到驅動的流程

Android震動vibrator(馬達)--系統到驅動的流程

一、前言

二、android驅動介紹

安卓總體架構是在 Linux核心基礎上,增加硬體抽象層(HAL),執行庫,java虛擬機器,程式框架等組成的,具體如下圖。


安卓的應用程式是從application framework層架構上建立的。所有APK應用程式都是通過framework層來執行的。application framework是google寫好的,除非自己深度定製,一般是不會更改這個層的。對於驅動開發來講,我們要做的就是讓framework層能認識並操作我們的硬體裝置就OK了。因此我們關心主要有3個層面:

linux Kernel層

HAL層

JNI層

1.       linuxKernel:是google在linux核心基礎上,專門為移動裝置優化後的核心,增加修改一些東西,擔修改的不多,對於核心驅動來講,基本沒有修改,做過linux驅動開發的人應該很容易理解。

2.       HAL,硬體抽象層:簡單來說,就是對Linux 核心驅動程式的封裝,向上提供介面,遮蔽低層的實現細節。也就是說,把對硬體的支援分成了兩層,一層放在使用者空間(User Space),一層放在核心空間(Kernel Space),其中,硬體抽象層執行在使用者空間。使用者空間不屬於核心不必遵守GPL協議,各個廠商可以把與自己硬體裝置相關,具有商業機密的一些程式碼放在HAL層。

3.       JNI層:提供java和底層C、C++的動態連結庫的介面。我理解的是JNI就是一個代理,可以把C和C++生成的介面函式翻譯成Java可用,提供給framework層。

三、振動系統開發過程

1.       硬體平臺

           CPU:IMX6Q4核1G

           RAM:1G

           FLASH:8G板載

   這次開發用的程式碼都是google和飛思卡爾提供的具體的就不再說明了,因為每個平臺程式碼都有所不同,而且買開發板時候都會帶相應的資料。

2.       震動系統是android裡面比較簡單的一個系統, 我採用的是從高層到底層的學習方式。因為我們的驅動最終是給應用程式用的,從application的需求分析JNI,然後分析HAL最後在我們寫linux kernel驅動時候,很容易理解為什麼要這麼寫。好了開始正式分析。

3.       Application層:通過google我找到關於APK訪問震動的如下說明:

A、通過系統服務獲得手機震動服務,Vibrator vibrator =(Vibrator)getSystemService(VIBRATOR_SERVICE); 

B、得到震動服務後檢測vibrator是否存在:

vibrator.hasVibrator();

檢測當前硬體是否有vibrator,如果有返回true,如果沒有返回false。

C、根據實際需要進行適當的呼叫,

vibrator.vibrate(longmilliseconds);

開始啟動vibrator持續milliseconds毫秒。    

vibrator.vibrate(long[]pattern, int repeat);

以pattern方式重複repeat次啟動vibrator。

(pattern的形式為new long[]{arg1,arg2,arg3,arg4......},其中以兩個一組的如arg1 和arg2為一組、arg3和arg4為一組,每一組的前一個代表等待多少毫 秒啟動vibrator,後一個代表vibrator持續多少毫秒停止,之後往復即 可。Repeat表示重複次數,當其為-1時,表示不重複只以pattern的方 式執行一次)。

D、vibrator.cancel();

Vibrator停止。

從上面的說明,可以看出應用程式呼叫震動系統,是呼叫一個叫VIBRATOR_SERVICE的服務,這個服務有3個函式,分別是hasVibrator(),r.vibrate,.cancel();當然這個三個函式可能在framework層進行的另一層的封裝,我沒有去深究。但可以推測出JNI層要做的是與註冊VIBRATOR_SERVICE服務和實現這三個函式相關的.

4.       HAL層:這一層我找到了具體的程式碼我們會好分析很多,其程式碼是:

android\frameworks\base\services\jni\ com_android_server_VibratorService.cpp

  1. #define LOG_TAG"VibratorService"
  2. #include"jni.h"
  3. #include"JNIHelp.h"
  4. #include"android_runtime/AndroidRuntime.h"
  5. #include<utils/misc.h>
  6. #include<utils/Log.h>
  7. #include<hardware_legacy/vibrator.h>
  8. #include<stdio.h>
  9. namespace android  
  10. {  
  11. static jbooleanvibratorExists(JNIEnv *env, jobject clazz)       //判斷振動器是否存在
  12. {  
  13.     return vibrator_exists() > 0 ? JNI_TRUE: JNI_FALSE;  
  14. }  
  15. static voidvibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms)//開啟振動器
  16. {  
  17.     // LOGI("vibratorOn\n");
  18.     vibrator_on(timeout_ms);  
  19. }  
  20. static voidvibratorOff(JNIEnv *env, jobject clazz)//關閉振動器
  21. {  
  22.     // LOGI("vibratorOff\n");
  23.     vibrator_off();  
  24. }  
  25. staticJNINativeMethod method_table[] = {  
  26.     { "vibratorExists","()Z", (void*)vibratorExists },  
  27.     { "vibratorOn""(J)V",(void*)vibratorOn },  
  28.     { "vibratorOff""()V",(void*)vibratorOff }  
  29. };  
  30. intregister_android_server_VibratorService(JNIEnv *env)    //註冊vibrator服務
  31. {  
  32.     return jniRegisterNativeMethods(env,"com/android/server/VibratorService",  
  33.             method_table, NELEM(method_table));  
  34. }  

從上面程式碼可以看出,JNI做了兩件事:其一註冊vibrator服務,其二,實現了vibratorExists,vibratorOn,vibratorOff三個服務函式。 進而我們可以分析出HAL層主要的就是實現次程式碼裡呼叫的三個函式vibrator_exists(),vibrator_on(timeout_ms),vibrator_off()。

5.       HAL層:經過各種查詢我們找到了vibrator的hal層程式碼:

\android40\hardware\libhardware_legacy\vibrator\vibrator.c

  1. #include<hardware_legacy/vibrator.h>
  2. #include"qemu.h"
  3. #include<stdio.h>
  4. #include<unistd.h>
  5. #include<fcntl.h>
  6. #include<errno.h>
  7. #define THE_DEVICE"/sys/class/timed_output/vibrator/enable"
  8. intvibrator_exists()         //判斷 振動器是否存在
  9. {  
  10.     int fd;  
  11. #ifdefQEMU_HARDWARE                 //模擬器情況下實現此功能
  12.     if (qemu_check()) {  
  13.         return 1;  
  14.     }  
  15. #endif
  16.     fd = open(THE_DEVICE, O_RDWR);  
  17.     if(fd < 0)  
  18.         return 0;  
  19.     close(fd);  
  20.     return 1;  
  21. }  
  22. static intsendit(int timeout_ms)       //開啟振動器 timeout_ms 毫秒
  23. {  
  24.     int nwr, ret, fd;  
  25.     char value[20];  
  26. #ifdefQEMU_HARDWARE        //模擬器情況下實現次功能
  27.     if (qemu_check()) {  
  28.         return qemu_control_command("vibrator:%d", timeout_ms );  
  29.     }  
  30. #endif
  31.     fd = open(THE_DEVICE, O_RDWR);  
  32. 相關推薦

    Android震動vibrator馬達--系統驅動流程

    一、前言 二、android驅動介紹 安卓總體架構是在 Linux核心基礎上,增加硬體抽象層(HAL),執行庫,java虛擬機器,程式框架等組成的,具體如下圖。 安卓的應用程式是從application framework層架

    Android A/B無縫系統更新

    原文:https://source.android.google.cn/devices/tech/ota/ab/   A/B 系統更新(也稱為無縫更新)的目標是確保在無線下載 (OTA) 更新期間在磁碟上保留一個可正常啟動和使用的系統。採用這種方式可以降低更新之後裝置無法啟動的可能

    android 電容屏驅動除錯之驅動程式分析篇

    關鍵詞:android  電容屏 tp 工作佇列 中斷 坐點計算  電容屏主要引數 平臺資訊: 核心:linux2.6/linux3.0 系統:android/android4.0  平臺:S5PV310(samsung exynos 4210)  作者:xubin3417

    Android原始碼編譯系統原始碼目錄

    Android 8.0之後原始碼目錄有所改變 Android平臺四層架構對應原始碼中的目錄: 第一層:應用程式層(applications)對應根目錄下packages/apps 第二層:應用程式框架層(application framework)對應根目錄下的f

    Android面試題31-App啟動流程

    先貼個連結,總結的挺全面 在看這篇文章之前,希望先看完我的之前的部落格 android面試(6)-Binder機制,因為關於App啟動流程設計很多Binder通訊; 先將“三個程序”,“六個大類”進行介紹: 三個程序: Launcher程序:整個App啟動流程的起點,

    Android解析ActivityManagerServiceAMS啟動流程和AMS家族

    前言 此前在Android系統啟動流程、應用程序以及深入四大元件這三個系列文章中,都提及到了AMS,但都沒有系統的來講解它,本文就以AMS為主來進行講解,其中會有一些知識點與這些系列文章有所重合,這裡會儘量做到詳盡講解。閱讀此文章前,最好閱讀相關文章中

    android遠端控制---從PC端寫資料到android系統驅動android系統

    技術難點1--- 第一步: 從PC端寫資料到android系統驅動讓android系統做出反應 2014年5月25日星期日 鏖戰了大半天,終於邁出了第一步 實現步驟: 1、手機通過資料線連上PC 2、開啟win7的cmd終端 3、在終端開啟android除錯工具 輸入命令a

    Android開發雜記1---截圖某個View並儲存到系統圖庫

    View view = new View(context) view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bitmap = Bitmap.createBitmap(mExa

    Android FrameWork學習Android系統原始碼除錯

    為了更進一步地學習跟研究 Android 系統原始碼,今天我們來講講如何進行 Android 系統原始碼的除錯,只有學會了如何進行系統原始碼的除錯,才能幫助我們更高效地閱讀跟理解原始碼。 我們知道,Android Framework 的程式碼主要由Java、C\

    嵌入式系統移植筆記 --第三方驅動移植黑盒子移植

    由於嵌入式系統分層,應用層要想操作硬體需通過核心層。驅動對上提供系統呼叫函式,對下封裝了對底層硬體的一些基本操作。筆者是不瞭解驅動程式的編輯,所以本章是在已經有驅動程式(fs4412_led_drv.c)和對應的應用程式(fs4412_led_app.c),來實現黑盒子移植(

    Android FrameWork學習Android 7.0系統原始碼下載\編譯

    最近計劃著研究下Android 7.0的系統原始碼,之前也沒做過什麼記錄,這次正好將學習的內容記錄下來,方便以後複習鞏固。 既然要學習我們的系統原始碼,那我們第一步要做的就是下載原始碼並進行編譯了。 硬體環境要求 1. 編譯環境 按照官方的說

    自編譯安卓系統分析Android核心漏洞

    目標 編譯Android4.4.3-r1原始碼及核心 0x00 環境 手機環境: nexus5 + Kernel3.4.0+Android4.4.3_r1 虛擬機器編譯環境: Vmware + Ubuntu 14.04 0x01 編

    Android底層開發在開發板中啟動Android系統

    1》燒錄uboot.bin——路徑:/home/george/src_210 cp uboot-fs210_V5/u-boot.bin /tftpboot/ FS210 # tftp 0x40008000 u-

    Android系統應用開發系統語言以及新增字型庫

    1.如何向android的setting語言列表中新增一門語言 第一種:修改配置檔案 位置:build/target/product/languages_full.mk| languages_small.mk,這兩個檔案裡頭,有PRODUCT_LOCALES := en_U

    Android Sip學習Android VoIP系統實現原理

      隨著我國三網融合的推進,VoIP與IPTV(Interactive Personality TV)一起成為這一龐大工程的重要標誌。而目前手機中,VoIP的解決方案並不是很多,特別是在Google公司推出的開源作業系統Android中。儘管該系統推出時間不長,憑藉強大的功能、良好的介面、廣泛的商業支援,

    Android開發筆記12——ListView & Adapter

    dba 只顯示一行 -1 ngs 而已 整理 adapt array xxx 轉載請註明:http://www.cnblogs.com/igoslly/p/6947225.html 下一章是關於ListFragment的內容,首先先介紹ListView的相關配置,理解L

    分布式系統的那些事兒 - 系統系統之間的調用

    數據格式 轉換 處理 分布 互調 圖片處理 動作 人性 並且 系統與系統之間的調用通俗來講,分為本地同一臺服務器上的服務相互調用與遠程服務調用,這個都可以稱之為RPC通信。淺白點講,客戶訪問服務器A,此時服務器要完成某個動作必須訪問服務器B,服務器A與B互相通信,相互調用,

    android權限permission大全

    wid 刪除 tro ica guard 格式 時區 禁用 經緯度 此文章由情緒控撰寫,轉載請註明此處!!! 1.android.permission.WRITE_USER_DICTIONARY 同意應用程序向用戶詞典中寫入新詞 2.android.permissi

    Android個人理解】跨應用調用不同組件的方法

    返回 使用 turn 數字 現實 rpc 文件夾 cas rgb 如果情景: 創建兩個應用appA和appB,appA包括一個Service,此Service有一個堵塞方法每隔10秒鐘產生一個隨機數字,例如以下: public int getRandom

    Android 編輯框EditText屬性學習

    藍色 區域 password border limit 文字 all 動作 方式 EditText繼承關系:View-->TextView-->EditText  EditText的屬性非常多,這裏介紹幾個: android:hint=&qu