传统 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 \

至此,完工

参考资料

相关推荐
crmscs7 分钟前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob9 分钟前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔14 分钟前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei99614 分钟前
flutter和Android动画的对比
android·flutter·动画
lxysbly2 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首3 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19435 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs5 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&6 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
LDORntKQH6 小时前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android