標籤:int 解決 回顧 com man obj base 缺點 system
考研已經過去了,android驅動的學習也斷了半年多了,現在重新撿起來學習,回顧一下Android驅動的大體架構。
Android系統的核心是java,其有一個David虛擬機器。Android-app操作硬體也相當於是java操作硬體。
在Linux系統上操作硬體是通過open read write等來實現,也就是操作C庫。如果java能直接調用C庫中的函數,也就解決了app操作硬體的問題。
下面的文章是java調用C/C++庫的方法。
1.方法1——jni調用底層驅動
在android架構中寫入c/c++直接調用底層linux驅動,並向上提供jni介面給應用程式:
優點:簡單易行;
缺點:主要在於驅動程式,由於在linux中需要遵循GPL協議,需要開源,而許多廠商的一些代碼不希望開源。
而且像螢幕等裝置可能需要多個app同時操作,這樣的話將會導致各種各樣的問題。
2.方法2——增加硬體抽象層
將驅動程式一分為二,一部分開源在核心中,一部分不開源在android架構中:
二、舉例led android驅動:
從這裡我們將看到整個應用程式框架層到底層驅動的走向。首先,無論是哪種方法,我們都需要實現一個linux驅動以供上層訪問led資源。
同樣也是通過jni來載入C庫,從而通過調用open等來實現對硬體的操作。Android為了實現多個APP能操作同一個硬體,硬體不由app來直接操作,而是有SystemServer來操作。app需要把請求通過serviceManager發給SystemServer,由SystemServer最終完成對硬體的操作。
這裡我們反過來思考一個app操作硬體的過程:
1、app需要申請服務和獲得服務getservice。
而這個服務是有介面完成的。所以第一步我們需要建立一個aidl檔案,來產生介面類。
frameworks/base/core/java/android/os/ILedService.aidl
同時修改 frameworks/base/Android.mk, 加入建立的aidl檔案。
2、自動產生ILedService.java
mmm frameworks/base/
編譯自動產生
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ILedService.java
ILedService.java檔案獲得了,現在就需要建立與之對應的java檔案,實現java下的對硬體操作的函數。
3、建立 LedService.java 實現介面函數
建立完LedService.java後將其放到frameworks/base/services/core/java/com/android/server/中,其上層Android.mk會自動包含此java檔案。
4、將服務註冊到Service Manager當中
修改frameworks/base/services/java/com/android/server/SystemServer.java
這樣的話,app就能獲得服務,從而實現對SystemServer的通訊,從而實現對硬體的操作。現在就是需要對SystemServer進行修改了。
SystemServer對硬體的操作也是jni,所以其也需要載入C/C++庫。在Android系統中已經把所有對硬體操作的jni檔案打包為一個.so庫,所以我們需要做的是在so庫中添加我們對硬體的支援。
5、實現com_android_server_LedService.cpp
將jni檔案放到frameworks/base/services/core/jni/目錄中。還要註冊native介面,在frameworks/base/services/core/jni/onload.cpp中修改。
並修改Android.mk檔案,加入com_android_server_LedService.cpp的編譯。
這裡其實已經差不多實現了對硬體的操作,因為我們實現了對cpp檔案的調用並打包進系統,cpp檔案就能直接載入C庫,調用open等函數實現對硬體的操作。
但是這樣的話有一個問題,就是如果驅動有點兒問題,我們就需要修改com_android_server_LedService.cpp,並重新編譯系統、燒寫系統。這樣的話不是很方便。我們可以再引入硬體抽象層(HAL),這樣更有利於搭建整個系統。
Android驅動學習-app調用核心驅動過程(驅動架構回顧)