Android framework HAL(HIDL)

简述

当你在Android系统中使用不同的硬件设备(例如摄像头、传感器、音频设备等)时,你需要与硬件抽象层(HAL)进行通信。 HAL是一个中间层,它充当了硬件和应用程序之间的桥梁。但是,由于硬件设备的不同,HAL接口在不同的硬件之间也会有所不同。这就是Android HAL接口定义语言(HIDL)的用武之地。

HIDL允许开发人员为每个硬件设备定义自己的接口。这些接口定义了硬件设备的功能和特性,包括输入参数、返回值和异常。使用这些接口,应用程序可以直接与硬件设备通信,而无需了解特定的硬件细节。在Android中,HIDL被广泛用于与HAL进行通信。

Android Project Treble被提出,在android O中被全面的推送,设计 HIDL 这个机制的目的,主要目的是把框架(framework)与 HAL 进行隔离,使得框架部分可以直接被覆盖、更新,而不需要重新对 HAL 进行编译。

HIDL 实际上是用于进行进程间通信(Inter-process Communication,IPC)的。进程间的通信可以称为 Binder 化(Binderized)。对于必须连接到进程的库,也可以使用 passthough 模式(但在Java中不支持)。

官方介绍

编写代码

Aosp代码目录中创建目录 hardware/interfaces/stksensor/1.0(有关1.0版本相关的,可以查看官网的版本管理概念),

1、新建文件IStksensor.hal

package android,[email protected];

improt IStksensorCallBack;

interface IStksensor {
    setCallBack(IStksensorCallBack callback);
    write(string data) generates (bool res);
    init() generates (MyResult result);
};

2、创建UDT(用户自定义类型),types.hal

package [email protected];

enum ResultCode : int32_t {
    UNKNOWN = -1,
    ERROR = 0,
    OK = 1,

};

struct MyResult{
    ResultCode resultCode;
    string msg;
};

3、新建文件回调文件IStksensorCallBack.hal

package [email protected];

interface IStksensorCallBack {
	passData(uint32_t data) generates (MyResult result);
};

使用hidl-gen生成相关文件

在终端执行以下命令,设置临时变量

PACKAGE=[email protected]
LOC=hardware/interfaces/stksensor/1.0/default

AOSP源码根目录执行hidl-gen生成default目录里的c++文件

hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE

AOSP源码根目录执行hidl-gen生成default目录里的Android.bp文件

hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE

AOSP源码根目录执行./hardware/interfaces/update-makefiles.sh会生成hardware/interfaces/stksensor/1.0/目录里的Android.bp文件

实现接口代码

修改hardware/interfaces/stksensor/1.0/default/Stksensor.cpp,这边实现单纯是打印日志

// FIXME: your file license if you have one

#include "Stksensor.h"
#include <log/log.h>

namespace android::hardware::stksensor::implementation {

// Methods from ::android::hardware::stksensor::V1_0::IStksensor follow.
Return<void> Stksensor::setCallBack(const sp<::android::hardware::stksensor::V1_0::IStksensorCallBack>& callback) {
    // TODO implement
	ALOGE("stksensor service have called the funtion of setCallBack");
    return Void();
}

Return<::android::hardware::stksensor::V1_0::ResultCode> Stksensor::write(const hidl_string& data) {
    // TODO implement
	ALOGE("stksensor service have called the funtion of write");
    return ::android::hardware::stksensor::V1_0::ResultCode {};
}

Return<void> Stksensor::init(init_cb _hidl_cb) {
    // TODO implement
	ALOGE("stksensor service have called the funtion of init");
    return Void();
}


// Methods from ::android::hidl::base::V1_0::IBase follow.

//IStksensor* HIDL_FETCH_IStksensor(const char* /* name */) {
    //return new Stksensor();
//}
//
}  // namespace android::hardware::stksensor::implementation

添加启动服务

1、在hardware/interfaces/stksensor/1.0/default/创建service.cpp

#define LOG_TAG "[email protected]"
#include <hidl/HidlTransportSupport.h>
#include <log/log.h>


using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardwara::stksensor::V1_0::IStksensor;
using android::hardware::stksensor::V1_0::implementation::Stksensor;
using namespace android;


int main() {
    configureRpcThreadpool(1, true);
	sp<IStksensor> service = new Stksensor();
    status_t status = service->registerAsService("stksensor"); 
    if (status != OK) {
		ALOGE("Error registering stksensor as service: %d", status);
        return status;
    }
	ALOGE("Ok to registering stksensor as service");
    joinRpcThreadpool();

    return 1;
}

2、在hardware/interfaces/stksensor/1.0/default/创建[email protected]启动脚本

service stksensor-hal-1-0 /vendor/bin/hw/[email protected]
    class hal
    user system
    group system

3、在hardware/interfaces/stksensor/1.0/default/创建[email protected]vintf

<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>android.hardware.stksensor</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IStksensor</name>
            <instance>stksensor</instance>
        </interface>
    </hal>
</manifest>

修改编译脚本

1、再修改hardware/interfaces/stksensor/1.0/default/Android.bp

// FIXME: your file license if you have one

cc_library_shared {
    // FIXME: this should only be -impl for a passthrough hal.
    // In most cases, to convert this to a binderized implementation, you should:
    // - change '-impl' to '-service' here and make it a cc_binary instead of a
    //   cc_library_shared.
    // - add a *.rc file for this module.
    // - delete HIDL_FETCH_I* functions.
    // - call configureRpcThreadpool and registerAsService on the instance.
    // You may also want to append '-impl/-service' with a specific identifier like
    // '-vendor' or '-<hardware identifier>' etc to distinguish it.
    name: "[email protected]",
    relative_install_path: "hw",
    // FIXME: this should be 'vendor: true' for modules that will eventually be
    // on AOSP.
    proprietary: true,
    srcs: [
        "Stksensor.cpp",
        "StksensorCallBack.cpp",
    ],
    shared_libs: [
        "libhidlbase",
        "libutils",
        "[email protected]",
    ],
}

cc_binary {
    name: "[email protected]",
    relative_install_path: "hw",
    defaults: ["hidl_defaults"],
    proprietary: true,
    init_rc: ["[email protected]"],
	vintf_fragments: ["[email protected]"],
    srcs: [
        "SerialPort.cpp",
        "service.cpp",
    ],
    shared_libs: [
        "libbase",
        "liblog",
        "libdl",
        "libutils",
        "libhardware",
        "libhidlbase",
        "libhidltransport",
        "[email protected]",
    ],
}

2、在device/$your_company/$SOC/device.mk添加

PRODUCT_PACKAGES += \
    [email protected] \
    [email protected]

现在stksensor目录结构

stksensor/
└── 1.0
    ├── Android.bp
    ├── default
    │   ├── Android.bp
    │   ├── [email protected]
    │   ├── [email protected]
    │   ├── service.cpp
    │   ├── StksensorCallBack.cpp
    │   ├── StksensorCallBack.h
    │   ├── Stksensor.cpp
    │   └── Stksensor.h
    ├── IStksensorCallBack.hal
    ├── IStksensor.hal
    └── types.hal

注意:会报一些avc权限 ,需要自己添加

猜你喜欢

转载自blog.csdn.net/weixin_45767368/article/details/129446255
今日推荐