传统 Hal 开发指南4 —— 实现一个简单的 Hal 模块

代码编写

接下来我们就来为我们上上节实现的玩具驱动写一个简单的 HAL 模块。

hardware/libhardware/include/hardware 目录下添加 hello_hal.h

cpp 复制代码
#ifndef _HARDWARE_HELLO_HAL_H
#define _HARDWARE_HELLO_HAL_H

#include <hardware/hardware.h>

__BEGIN_DECLS

#define HELLO_HAL_API_VERSION HARDWARE_MODULE_API_VERSION(1,0)

#define HELLO_HAL_HARDWARE_MODULE_ID "hello_hal"


#define HELLO_HAL_DEVICE_ID_MAIN "main_hello_hal"

struct hello_hal_device_t;

typedef struct hello_hal_device_t {
   
    struct hw_device_t common;

    int (*hello_hal_open)(struct hello_hal_device_t* hello_hal_dev);

    int (*hello_hal_read)(struct hello_hal_device_t* hello_hal_dev, char* str);

    int (*hello_hal_write)(struct hello_hal_device_t* hello_hal_dev,const char* str);
} hello_hal_device_t;

static inline int hello_hal_methods_open(const struct hw_module_t* module, hello_hal_device_t** device)
{
    return module->methods->open(module, HELLO_HAL_DEVICE_ID_MAIN, (struct hw_device_t**)device);
}

__END_DECLS

#endif  // _HARDWARE_VIBRATOR_H

这里的核心是:

  • 实现一个 hello_hal_device_t 结构体,这个结构体用于操作具体的硬件
  • 实现 hello_hal_methods_open 函数,这个函数用于从 hw_module_t 从找到 hello_hal_device_t 结构体实例

接着在 hardware/libhardware/modules/ 目录下添加 hello_hal 目录,并在 hello_hal 目录下添加源码文件 hello_hal.c

cpp 复制代码
#include <hardware/hello_hal.h>
#include <hardware/hardware.h>

#include <cutils/log.h>

#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>


int fd;

int hello_open (struct hello_hal_device_t* hello_hal_dev) {

    fd = open("/dev/hello", O_RDWR);
    if (fd == -1)
	{
		printf("can not open file /dev/hello\n");
		return -1;
	}

    return 0;
}
    
int hello_close (struct hello_hal_device_t* hello_hal_dev) {

    close(fd);
    free(hello_hal_dev);
    return 0;
}

int hello_read (struct hello_hal_device_t* hello_hal_dev, char* str) {
    char buf[1024];
	int len = read(fd, buf, 1024);
    if (len > 0)
    {
        buf[1023] = '\0';
	    str = buf;
        return len;
    } else {
        return -1;
    }	
}

int hello_write (struct hello_hal_device_t* hello_hal_dev,const char* str) {
    int len = strlen(str) + 1;
	len = len < 1024 ? len : 1024;
	return write(fd, str, len);
}


static int hello_hal_open(const hw_module_t* module, const char* id __unused,
                      hw_device_t** device __unused) {

    hello_hal_device_t *hello_hal_dev = calloc(1, sizeof(hello_hal_device_t));

    if (!hello_hal_dev) {
        ALOGE("Can not allocate memory for the hello hal device");
        return -ENOMEM;
    }

    hello_hal_dev->common.tag = HARDWARE_DEVICE_TAG;
    hello_hal_dev->common.module = (hw_module_t *) module;
    hello_hal_dev->common.version = HARDWARE_DEVICE_API_VERSION(1,0);
    hello_hal_dev->common.close = hello_close;

    hello_hal_dev->hello_hal_open = hello_open;
    hello_hal_dev->hello_hal_write = hello_write;
    hello_hal_dev->hello_hal_read = hello_read;   

    *device = (hw_device_t *) hello_hal_dev;

    return 0;
}


static struct hw_module_methods_t hello_hal_module_methods = {
    .open = hello_hal_open,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .module_api_version = HELLO_HAL_API_VERSION,
    .hal_api_version = HARDWARE_HAL_API_VERSION,
    .id = HELLO_HAL_HARDWARE_MODULE_ID,
    .name = "Default Hello  HAL",
    .author = "ahaoframework",
    .methods = &hello_hal_module_methods,
};
  • 声明一个 hw_module_t 结构体实例
  • 申明一个 hw_module_methods_t 结构体实例,其中 open 函数指针指向 hello_hal_open
  • hello_hal_open 会构建一个 hello_hal_device_t 结构体实例,对其成员赋值,核心的成员主要是 hello_hal_open hello_hal_write hello_hal_read 三个函数指针

编译系统配置

接着在 hardware/libhardware/modules/hello_hal 目录下添加 Android.mk

Makefile 复制代码
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello_hal.default

# HAL module implementation stored in
# hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.so
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := hello_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)

接着在 hardware/libhardware/modules/Android.mk 中添加 hello_hal,这样编译系统才会去编译 hello_hal 模块。

Makefile 复制代码
hardware_modules := gralloc hwcomposer audio nfc nfc-nci local_time \
	power usbaudio audio_remote_submix camera usbcamera consumerir sensors vibrator hello_hal \
	tv_input fingerprint input vehicle thermal vr
include $(call all-named-subdir-makefiles,$(hardware_modules))

接着在 product 配置文件 build/target/board/generic_x86_64/device.mk 中添加 hello_hal.default 库:

Makefile 复制代码
PRODUCT_PACKAGES := \
    audio.primary.goldfish \
    hello_hal.default \
    vibrator.goldfish \

至此,完工

参考资料

相关推荐
阿巴斯甜5 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker6 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95277 小时前
Andorid Google 登录接入文档
android
黄林晴8 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab20 小时前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android