硬件抽象层是位于操作系统 内核与硬件电路之间的接口层,其目的在于将硬件抽象化。它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可在多种平台上进行移植。在Android内核源码(不是linux内核源码)中添加HAL层、JNI层、开启系统服务,这是一个比较复杂的过程,很多标准的设备都采用这种方式设计,比如说wifi、gps、sensor等,这种调用过程看起来比较标准,但是如果作为第三方开发就会很麻烦,HAL层、JNI层,系统服务层,每层都需要编译Android内核源码,这样就会延长了产品的开发周期,所以编写本文意在简化应用层与驱动的交互逻辑,虽增加耦合,但在平台有限的开发环境中能大大提高开发效率,可从应用层调试驱动减少系统编译和排错的成本。
相关文件地址:
AndroidM_3561_after/vendor/xxx/packages/apps/Radio/app/src/main/jni/RadioDriveJni.cpp
可参照FaRadioService.cpp,实现节点的open/close/read/write
extern "C"
JNIEXPORT jint JNICALLJava_com_xxx_radio_radiodrive_RadioDriveJni_init(JNIEnv *env, jobject instance) {
fd = open(DEVICE_NAME, O_RDWR);
if(fd < 0)
{
LOGE("Fail to open device file /dev/FlyRadio --%s.",DEVICE_NAME); return -1; }
return 0;
}
extern "C"
JNIEXPORT jint JNICALLJava_com_xxx_radio_radiodrive_RadioDriveJni_setMute(JNIEnv *env, jobject instance, jboolean muted) {
unsigned char buf[5] = {0xa0,0x66,0x01,0x00};
buf[3] = muted;
mMute = muted;
if(write(fd, buf,sizeof(buf)))
{
return 0;
}
return -1;
}
extern "C"
JNIEXPORT jboolean JNICALLJava_com_xxx_radio_radiodrive_RadioDriveJni_destroy(JNIEnv *env, jobject instance) {
if(fd != -1){
if(!close(fd)){
return 0;
}
}
return -1;
}
相关文件地址:
AndroidM_3561_after/vendor/xxx/packages/apps/Radio/app/src/main/jni/Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
RadioDriveJni.cpp \
LOCAL_SHARED_LIBRARIES := libutils libcutils
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
ifneq ($(XXX_LIB_OUT_PATH),)
LOCAL_MODULE_PATH := $(XXX_LIB_OUT_PATH)
endif
LOCAL_MODULE:= libfaradio_drive_jni
include $(BUILD_SHARED_LIBRARY)
相关文件地址:
AndroidM_3561_after/vendor/xxx/packages/apps/RadioAndroid.mk
include $(LOCAL_PATH)/app/src/main/jni/Android.mk
相关文件地址:
AndroidM_3561_after/system/core/rootdir/device.mk
PRODUCT_PACKAGES += libfaradio_drive_jni
相关文件地址:
AndroidM_3561_after/system/core/rootdir/ueventd.rc
AndroidM_3561_after/external/sepolicy/system_app.te
在ueventd.rc中添加,
/dev/FlyRadio 0666 system system
在system_app.te中添加,’ fly_radio_device ’ 为/dev/FlyRadio节点在file_contexts文件中的定义
allow system_app fly_radio_device:chr_file rw_file_perms;
根据结构图一步一步定位再移除
1.移除Hal层
相关文件地址:
AndroidM_3561_after/hardware/libhardware/modules/xxx/FlyRadioHal.c
AndroidM_3561_after/hardware/libhardware/modules/xxx/Android.mk
直接删除即可
相关文件地址:
AndroidM_3561_after/vendor/xxx/frameworks/native/faradio/service/FaRadioService.h
AndroidM_3561_after/vendor/xxx/frameworks/native/faradio/service/FaRadioService.cpp
AndroidM_3561_after/vendor/xxx/frameworks/native/faradio/service/IaRadioService.h
AndroidM_3561_after/vendor/xxx/frameworks/native/faradio/service/IaRadioService.cpp
直接删除即可
由于这里没有Android.mk文件,所有应该被父目录相应的Android.mk文件引入,在AndroidM_3561_after/vendor/xxx/frameworks/native/faradio/中查看Android.mk,果然有对service文件夹的引入,删除即可
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/service \
相关文件地址:
AndroidM_3561_after/vendor/xxx/frameworks/native/launcher/ServicesLauncher.cpp
注释掉FaRadioService启动的代码即可
extern "C" void instantiateServices(int tag){
if(tag == 1){
int status = launchService("/system/lib/libfaradioservice.so");
if(status == -1)
ALOGE("ServicesLauncher load library Error.");
}
}
相关文件地址:
AndroidM_3561_after/vendor/xxx/frameworks/base/jni/com_xxx_radio_Radio.cpp
直接删除即可,和2一样移除相关Andorid.mk对此文件的依赖
###5.移除device.mk对已移除module的依赖
相关文件地址:
AndroidM_3561_after/vendor/xxx/device/device.mk
# PRODUCT_PACKAGES += \
# libfaradioservice \
# add xxx radio
# PRODUCT_PACKAGES += radio.default