(安卓/android)应用层绕过HAL调用驱动

应用层绕过HAL调用驱动(以Radio为例)

为什么要绕过Hal层调用驱动

  • 硬件抽象层是位于操作系统 内核与硬件电路之间的接口层,其目的在于将硬件抽象化。它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可在多种平台上进行移植。在Android内核源码(不是linux内核源码)中添加HAL层、JNI层、开启系统服务,这是一个比较复杂的过程,很多标准的设备都采用这种方式设计,比如说wifi、gps、sensor等,这种调用过程看起来比较标准,但是如果作为第三方开发就会很麻烦,HAL层、JNI层,系统服务层,每层都需要编译Android内核源码,这样就会延长了产品的开发周期,所以编写本文意在简化应用层与驱动的交互逻辑,虽增加耦合,但在平台有限的开发环境中能大大提高开发效率,可从应用层调试驱动减少系统编译和排错的成本。

  • 简化前后结构概览
    在这里插入图片描述

一. 创建访问驱动的新方式

1.编写Jni代码访问驱动节点

相关文件地址:

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;
}

2.新建Android.mk文件跟随系统一起编译到system/lib目录,module命名为’ libfaradio_drive_jni ’

相关文件地址:

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)

3.Radio根目录下的Android.mk文件里引入上述创建的mk文件

相关文件地址:

AndroidM_3561_after/vendor/xxx/packages/apps/RadioAndroid.mk

include $(LOCAL_PATH)/app/src/main/jni/Android.mk

4.将libfaradio_drive_jni module 添加到device.mk白名单

相关文件地址:
AndroidM_3561_after/system/core/rootdir/device.mk

PRODUCT_PACKAGES += libfaradio_drive_jni

5.赋予应用读写驱动节点的权限

相关文件地址:
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

直接删除即可

2.移除Service

相关文件地址:

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 \

3.移除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.");
    }
}

4.移除调用FaradioService的Jni封装

相关文件地址:

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

三. 编译系统

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值