HAL stub

lethe1203發表於2024-04-04
每種硬體都對應了一個HAL模組,實現HAL,需要滿足HAL的相關規則,規則定義在原始碼hardward目錄下,標頭檔案hardward.h,C檔案hardward.c。

1、重要結構體:

hardward.h中定義了三個重要的結構體:
struct hw_module_t;
struct hw_module_methods_t;
struct hw_device_t;
a、結構體hw_module_t代表hal模組 ,hal模組需自定義一個結構體,並且該struct包含hw_module_t結構體,且模組的tag必須為HARDWARE_MODULE_TAG,表示hal模組的結構體。
b、結構體hw_module_methods_t代表模組的操作方法列表,它內部只有一個函式指標open,用來開啟該模組下的裝置
c、結構體hw_device_t代表該模組下的裝置,hal模組需要自定義一個結構體,且必須包含 hw_device_t。
d、最後這個模組定義好之後還必須匯出符號HAL_MODULE_INFO_SYM,指向這個模組,HAL_MODULE_INFO_SYM定義在hardware.h中值為“HMI”

2、上層如何與hal進行通訊:

透過HAL_MODULE_INFO_SYM,google hal與qcom hal部分進行繫結,上層也透過HAL_MODULE_INFO_SYM獲取到hal層的相關介面,獲取到hal模組使用hw_get_module函式。

3、實現加減的簡單hal實現

在hardware/libhardware/include/hardware目錄下建立lethe.h:
在該標頭檔案中我們自定義裝置結構體,在該裝置結構體中宣告add和subtract函式。
#include <stdint.h>
#include <stdbool.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <cutils/native_handle.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>

// hal模組名
#define LETHE_HARDWARE_MODULE_ID "lethe"

// hal版本號
#define LETHE_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(0, 1)

#define HARDWARE_LETHE "lethe"

// 自定義hal模組結構體
typedef struct lethe_module {
        struct hw_module_t common;      // 第一個變數必須為hw_module_t
} lethe_module_t;

// 自定義hal裝置結構體
typedef struct lethe_device {
        struct hw_device_t common;

        // 加法函式
        int (*add)(const struct lethe_device *dev, int a, int b, int *total);

        // 減法函式
        int (*subtract)(const struct lethe_device *dev, int a, int b, int *total);

} lethe_device_t;

static inline int lethe_open_test(const struct hw_module_t *module,
                lethe_device_t **device) {
        return module->methods->open(module, HARDWARE_LETHE, (struct hw_device_t **)device);
} 
在hardware/libhardware目錄下新建lethe資料夾:
在lethe.c檔案中主要匯入符號HAL_MODULE_INFO_SYM,用來指向自定義模組,編寫模組相關函式介面:
#include <malloc.h>
#include <stdint.h>
#include <string.h>
#include <log/log.h>
#include <hardware/lethe.h>
#include <hardware/hardware.h>

static int add(const struct lethe_device *dev, int a, int b, int *total)
{
        if (!dev) {
                return -1;
        }
        *total = a + b;
        return 0;
}

static int subtract(const struct lethe_device *dev, int a, int b, int *total)
{
        if (!dev) {
                return -1;
        }
        *total = a - b;
        return 0;
}

static int lethe_close(hw_device_t *dev)
{
        if(dev) {
                free(dev);
                return 0;
        } else {
                return -1;
        }
}

//開啟裝置函式
static int lethe_open(const hw_module_t* module,const char __unused *id,
                            hw_device_t** device)
{
    if (device == NULL) {
        ALOGE("NULL device on open");
        return -1;
    }

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

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = LETHE_MODULE_API_VERSION_1_0;
    dev->common.module = (struct hw_module_t*) module;
    dev->common.close = lethe_close;
    dev->add = add;
    dev->subtract = subtract;

    *device = &(dev->common);
    return 0;
}

static struct hw_module_methods_t lethe_module_methods = {
    .open = lethe_open,
};

//匯出符號HAL_MODULE_INFO_SYM,指向自定義模組
lethe_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = LETHE_MODULE_API_VERSION_1_0,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = LETHE_HARDWARE_MODULE_ID,
        .name               = "lethe hal",
        .author             = "lethe",
        .methods            = &lethe_module_methods,
    },
};

編寫Android.bp檔案就可以生成自己的hal庫:
cc_library_shared {                     //共享庫,.so結尾                
        relative_install_path: "hw",
        proprietary: true,
        srcs: ["lethe.c"],
        header_libs: ["libhardware_headers"],
        shared_libs: ["liblog"],
}

Lethetest.cpp用來測試hal:
#include <hardware/hardware.h>                                                         
#include <hardware/lethe.h>
#include <log/log.h>

int main()
{
        lethe_device_t* lethe_device = NULL;

        const lethe_module_t *module = NULL;

        // 用來獲取lethe模組
        int ret = hw_get_module(LETHE_HARDWARE_MODULE_ID, (const struct hw_module_t** )&module);

        if (!ret) {
                ret = lethe_open_test((const struct hw_module_t*)module, &lethe_device);
        }

        if (ret < 0) {
                ALOGE("get lethe hal failed ......");
                return -1; 
        }

        int total = 0;
        lethe_device->add(lethe_device, 5, 3, &total);
        ALOGE("[lethe]======== add 5 + 3 = %d", total);
        lethe_device->add(lethe_device, 5, 3, &total);
        ALOGE("[lethe]======== subtract  5 - 3 = %d", total);
}

執行./lethe_test進行hal測試,測試結果如下:
[lethe]======== add 5 + 3 = 8
[lethe]======== add 5 - 3 = 2

相關文章