HAL层编写

Posted by on March 3, 2022

##开源自己编写的HAL层代码在,hardware/libhardware 目录下面,具体步奏 用系统自己的实例代码fingerprint例子

  • 首先在hardware/libhardware/include/hardware目录下创建fingerprint.h文件


#ifndef ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H
#define ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H

#include <hardware/hardware.h>
#include <hardware/hw_auth_token.h>
HAL版本号
#define FINGERPRINT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
 HAL模块名 
#define FINGERPRINT_HARDWARE_MODULE_ID "fingerprint"



 #定义的具体方法
typedef struct fingerprint_device {
    /**
    必须 写死不能省略
     * Common methods of the fingerprint device. This *must* be the first member
     * of fingerprint_device as users of this structure will cast a hw_device_t
     * to fingerprint_device pointer in contexts where it's known
     * the hw_device_t references a fingerprint_device.
     */
    struct hw_device_t common;

    fingerprint_notify_t notify;

    第一个参数必须是device结构体,在device中定义的方法
    int (*set_notify)(struct fingerprint_device *dev, fingerprint_notify_t notify);

  
    uint64_t (*pre_enroll)(struct fingerprint_device *dev);

} fingerprint_device_t;
# 必须模块
typedef struct fingerprint_module {
    /**
    写死不能省略
     * Common methods of the fingerprint module. This *must* be the first member
     * of fingerprint_module as users of this structure will cast a hw_module_t
     * to fingerprint_module pointer in contexts where it's known
     * the hw_module_t references a fingerprint_module.
     */
    struct hw_module_t common;
} fingerprint_module_t;

#endif  /* ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H */

  • 接着在hardware/libhardware/modules/目录下创建一个fingerprint的文件夹,里面包含一个fingerprint.c和Android.bp,看原生fingerprint.c文件

#define LOG_TAG "FingerprintHal"

#include <errno.h>
#include <malloc.h>
#include <stdint.h>
#include <string.h>

#include <log/log.h>
引入在hardware/libhardware/include/hardware下创建的fingerprint.h文件
#include <hardware/fingerprint.h>
#include <hardware/hardware.h>
#关闭设备
static int fingerprint_close(hw_device_t *dev)
{
    if (dev) {
        free(dev);
        return 0;
    } else {
        return -1;
    }
}

set_notify 的具体实现类
static int set_notify_callback(struct fingerprint_device *dev,
                                fingerprint_notify_t notify) {
    /* Decorate with locks */
    dev->notify = notify;
    return FINGERPRINT_ERROR;
}
#打开设备
static int fingerprint_open(const hw_module_t* module, const char __unused *id,
                            hw_device_t** device)
{
    if (device == NULL) {
        ALOGE("NULL device on open");
        return -EINVAL;
    }

    fingerprint_device_t *dev = malloc(sizeof(fingerprint_device_t));
    memset(dev, 0, sizeof(fingerprint_device_t));

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = FINGERPRINT_MODULE_API_VERSION_2_0;
    dev->common.module = (struct hw_module_t*) module;
    dev->common.close = fingerprint_close;

    dev->pre_enroll = fingerprint_pre_enroll;
    dev->enroll = fingerprint_enroll;
    dev->get_authenticator_id = fingerprint_get_auth_id;
    dev->cancel = fingerprint_cancel;
    dev->remove = fingerprint_remove;
    dev->set_active_group = fingerprint_set_active_group;
    dev->authenticate = fingerprint_authenticate;
    映射的具体实现方法
    dev->set_notify = set_notify_callback;
    dev->notify = NULL;

    *device = (hw_device_t*) dev;
    return 0;
}

static struct hw_module_methods_t fingerprint_module_methods = {
    .open = fingerprint_open,
};

导出符号HAL_MODULE_INFO_SYM,指向自定义模块
fingerprint_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag= HARDWARE_MODULE_TAG,  
        .module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
// 暴露给外部调用获取对象的 TAG 类似于      hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID,(hw_module_t const**)&module); 给外部调用 类似于 
        .id                 = FINGERPRINT_HARDWARE_MODULE_ID,
        .name               = "Demo Fingerprint HAL",
        .author             = "The Android Open Source Project",
        .methods            = &fingerprint_module_methods,
    },
};



  • Android.bp文件
cc_library_shared {
    这个就是编译出来的so库的名字
    name: "fingerprint.default",
    relative_install_path: "hw",
    proprietary: true,
    srcs: ["fingerprint.c"],
    cflags: ["-Wall", "-Werror"],
    header_libs: ["libhardware_headers"],
    shared_libs: ["liblog"],
}
  • 在Andorid根目录下编译初始化编译环境

    source build/envsetup.sh lunch xx 执行编译 mmm hardware/libhardware/modules/fingerprint/

    编译成功以后就会在out目录下生成共享fingerprint.default.so库,这个库就是可以在HIDL层或者JNI层直接调用了