歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 從HAL層到Java應用層重寫mini6410 LED功能

從HAL層到Java應用層重寫mini6410 LED功能

日期:2017/3/1 10:12:26   编辑:Linux編程

從HAL層到java應用層重寫mini6410 led功能

記錄了我從HAL層到應用層如何把led這個設備控制實現的過程。如果有遺漏或者錯誤,請各位高手指點。

led驅動的代碼就不說了,以後有空再實現,
第一步,查看linux驅動設備是否工作正常。之後所有的一切,都是在這個leds設備的基礎上操作完成的,所以,檢查這個設備是不是有用成為了一個很重要的關鍵。
首先,用adb shell查看Android dev下的目錄,發現有leds這個設備:
ls -l /dev/leds 這個設備文件就是android中間層用來操作Linux底層led設備的。
回到android2.3.4源代碼目錄,在 external目錄底下建立testDev目錄,在下面分別建立Android.mk 和 testDev.c文件
在testDev.c這個文件裡,首先寫一個測試程序用來測試Leds這個文件設備能否正常運行;
testDev.c,打開設備關鍵是ioctl這個函數,其中,第二個參數用來控制是否打開一個led設備,第三個參數用來控制打開的是那個led。(testDev.c 和 Android.mk這2個程序可以見附件。)
全部寫完之後,用./build-android編譯一下,編譯的時候,可以指定特定模塊編譯,這樣比較節省時間。不能用mmm這個命令編譯,這個編譯了之後product的名稱就不是mini6410了,這樣很多庫都會找不到。編譯之後android的out/target/product/mini6410/system/bin/ 目錄下面會生成一個叫 testDev的文件,然後將開發板開機,用adb push out/target/product/mini6410/system/bin/testDev system/bin/ 把testDev push到開發板上面去,然後用adb shell命令進入到system/bin/目錄下面,運行./testDev 就可以檢測leds這個設備是否運行正常。

第二步,為linux的led驅動提供android的HAL層。
HAL是android的硬件邏輯層,在這裡,主要是為framework層提供一層Led的操作接口。直接操作leds設備的函數在第一步已經指明了,就是ioctl函數,但是,如何將這個功能增加到android的框架裡呢?
首先,增加hardware/libhardware/modules/目錄下的mydevice目錄,然後在這個目錄下再新建Led目錄,在led目錄下,分別建立led.c和Android.mk文件在mydevice這個目錄下,也需要建立Android.mk文件用來搜索mydevice目錄下的每個驅動設備目錄。在hardware/libhardware/include/hardware 下,建立hardware目錄,在下層建立mydevice/led.h,該文件用來實現一些module_id之類的宏和結構體,這裡比較重要的是DEVICE_NAME一定要寫對,這個就是程序需要讀取的設備,還有MODULE_NAME的取名要跟Android.mk裡面的LOCAL_MODULE前綴一樣,否則程序加載的時候會找不到。硬件結構體是繼承hw_device_t這個結構的,在這個結構體裡,可以定義leds設備的fd,和這個設備需要操作的一些結構函數,比如這邊就增加了set_led,用來控制Led設備的。
最後還要修改hardware/libhardware/ Android.mk,將增加好的led結構添加進去。
include $(addsuffix /Android.mk, $(addprefix $(LOCAL_PATH)/, \
modules/gralloc \
modules/mydevice \ --》增加這行
tests \
))

然後編譯一下,out/target/product/mini6410/system/lib/hw目錄下會生成led.default.so這個文件,編譯就成功了。

第三步,增加jni底層對上層的應用接口。
在這一步當中,封裝了底層的.c的接口函數,使得上層Java可以調用, 做到這一步,java應用層應該也可以調用這一步生成的.so,友善提供的.so文件應該就是做到這一步生成的。
這一步當中,首先添加framework/base/services/jni目錄下的com_android_server_DeviceService.cpp文件,這個文件用來動態加載jni的接口函數。為java上層提供幫助。Method_table這個表提供了底層到Java層的映射,
static const JNINativeMethod method_table[]=
{
{"openLed", "()Z", (void*)led_init}, --》第一個是java層可以調用的函數名,第二個是函數簽名,第三個是本層函數名
{"set_Led", "(II)I", (void*)setLed},
};
java層調用映射之後的字符就可以完成對底層的通訊了。全部寫完之後,還要在frameworks/base/services/jni/onload.cpp這個文件當中將method_table這個表加載進系統裡(JNI_OnLoad),然後在Android.mk下增加com_android_server_DeviceService.cpp文件就可以編譯了。
LOCAL_SRC_FILES:= \
com_android_server_AlarmManagerService.cpp \
com_android_server_BatteryService.cpp \
com_android_server_InputManager.cpp \
com_android_server_LightsService.cpp \
com_android_server_PowerManagerService.cpp \
com_android_server_SystemServer.cpp \
com_android_server_UsbService.cpp \
com_android_server_VibratorService.cpp \
com_android_server_location_GpsLocationProvider.cpp \
com_android_server_DeviceService.cpp \ --》增加這行。
onload.cpp

第四步,用aidl增加java services。
Aidl是一個工具,他可以用來增加java的services,首先,在frameworks/base/core/java/android/os/路徑下增加IDeviceService.aidl接口,然後,在 frameworks/base/Android.mk裡面增加這個aidl文件,編譯一下,這個時候就會生成stub,新增frameworks/base/services/java/com/android/server這個路徑下的DeviceService.java,這個java文件裡需要繼承剛才用aidl工具生成出來的IDeviceService.Stub,之後對jni接口進行再一次封裝。在frameworks/base/services/java/com/android/servier/SystemServer.java裡面需要增加這個服務,之後重新編譯程序就可以了。

第五步,在java應用層調用底層編譯好的java service服務。
用eclipse新建一個java項目,然後在這個新建的工程裡面把操作的button做好,這個界面由於只是測試程序,所以就做了一個button,這個button的功能就是依次打開和關閉led燈。

資源下載:用到的程序

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2012年資料/8月/16日/從HAL層到Java應用層重寫mini6410 LED功能/

Copyright © Linux教程網 All Rights Reserved