Android HAL介面實現
總體結構
如果要實現一個HAL對應native層的介面,必須要明確一下整個結構。
HAL層的程式碼將會被封裝成一個硬體模組,比如sensor.xxx.so的so庫,該模組會通過kernel註冊,然後在native程式碼層次呼叫該系統模組,使用其中的函式,類等等。
native層的實現可以有很多的用途,比如寫成java的JNI實現,或則是編譯成so庫供其他的native層程式碼使用。
HAL層實現
HAL函式實現
自己比較熟悉的是Sensor感測器模組,就以這個模組為例。
首先,在libhardware/sensor.h檔案中新增想要新增的功能函式的介面。
int (*get_val)(struct sensors_poll_device_t *dev,float* data);
然後在HAL層添加註冊硬體模組的程式碼
struct sensors_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: SENSORS_HARDWARE_MODULE_ID,
name: "XXX module" ,
author: "XXX",
methods: &sensors_module_methods,
dso: NULL,
reserved: {0}
},
get_sensors_list: sensors__get_sensors_list,
};
其中tag: HARDWARE_MODULE_TAG
是固定的寫法,這樣寫才能被kernel註冊模組時所識別。
之後在HAL新增具體的函式實現
int sensors_poll_context_t::get_val(float * data){
LOGD("get_val into in HAL......");
int i;
//返回了0-15共16個數字做示例
for(i=0;i<16;i++)
{
data[i]=i;
}
return 0;
}
編譯HAL程式碼成so庫
編譯的話就需要用到Android.mk檔案了,語法不在細講,需要根據自己的需求去更改。我的示例程式碼中,會生成一個snesors.xxx.so的庫檔案,這個so檔案放至Android機器的system/lib/hw的資料夾下,就可以被使用了。
Native層實現
Native程式碼實現
可以新建 xxSensor.cpp和xxSensor.h檔案,在cpp檔案中實現module的開啟。
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);
然後呼叫模組中的open函式開啟sensor硬體(開啟實際上就是傳回了一個類,該類實現了HAL層的函式功能等等)
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
之後直接呼叫mSensorDevice->get_val()
就能使用該函數了。
當然,在native層,我們還是封裝一下這個呼叫比較好.
status_t SensorDevice::get_val(float* data){
if (!mSensorDevice) return NO_INIT;
int temp= mSensorDevice->get_val(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),data);
ALOGD("SensorDevice get_val");
return temp;
}
JAVA介面JNI的實現
封裝成so庫供其他的native層程式碼呼叫
在native層可以自己新建一個cpp和h檔案,在裡面直接使用SensorDevice的函式比如
int mySensor::get_val(float data[16]){
android::SensorDevice& dev(android::SensorDevice::getInstance());
ALOGD("mySensor get_val");
return dev.get_val(data);
}
如果想要封裝成直接可以用dlopen開啟的so庫的話,可以新增一個extern"c"
將函式開一個介面
extern "C"{
int n_get_val(float data[16])
{
return mySensor.get_val(data);
}
}
最後在mk檔案中將自己寫的程式碼編譯成so庫
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=\
mySensor.cpp \
SensorDevice.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
libhardware_legacy \
libutils \
liblog \
libbinder \
libui \
libgui \
libsensorservice
LOCAL_MODULE:=mysensor
include $(BUILD_SHARED_LIBRARY)
其中SRC_FILE要包含自己的cpp檔案和引用的cpp檔案,SHARED_LIBRARIES檔案則包含應用的所有庫。
編譯生成mysensor.so檔案,最後將mysensor.so和mysensor.h給其他人就可以直接在native層使用了。