Android 6.0中添加硬件抽象层(HAL)

在目录hardware/libhardware/include/hardware中添加freg.h文件

hardware/
└── freg.h

在目录hardware/libhardware/modules中添加freg目录,并在freg目录中添加如下文件

freg/
├── Android.mk
└── freg.cpp

freg.h和freg.cpp是源代码文件, Android.mk是模块的编译脚本文件

freg.h文件代码

/*************************************************************************
* 文件: freg.h
* 作者: fantasy
* 邮箱: fantasy@gmail.com 
* 创建时间: 2016年07月22日 星期五 20时17分16秒
*************************************************************************/

#ifndef ANDROID_FREG_INTERFACE_H
#define ANDROID_FREG_INTERFACE_H

#include <hardware/hardware.h>

__BEGIN_DECLS

/**
 * 定义模块ID
 */
#define FREG_HARDWARE_MODULE_ID "freg"

/**
 * 定义设备ID
 */
#define FREG_HARDWARE_DEVICE_ID "freg"

#define FREG_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
#define FREG_MODULE_API_VERSION_CURRENT FREG_MODULE_API_VERSION_1_0


#define FREG_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
#define FREG_DEVICE_API_VERSION_CURRENT FREG_DEVICE_API_VERSION_1_0

/**
 * 自定义模块结构体
 */
struct freg_module_t{
    struct hw_module_t common;
};


/**
 * 自定义设备结构体
 */
struct freg_device_t{
    struct hw_device_t common;
    int fd;
    int (*set_val)(struct freg_device_t *dev, int val);
    int (*get_val)(struct freg_device_t *dev, int *val);
};

__END_DECLS

#endif

freg.cpp文件

/*************************************************************************
* 文件: freg.cpp
* 作者: fantasy
* 邮箱: fantasy@gmail.com 
* 创建时间: 2016年07月22日 星期五 20时25分31秒
*************************************************************************/

#define LOG_TAG "freg_hw"

#include <hardware/hardware.h>
#include <hardware/freg.h>

#include <fcntl.h>
#include <errno.h>
#include <malloc.h>

#include <cutils/log.h>
#include <cutils/atomic.h>

#define DEVICE_NAME "/dev/freg"
#define MODULE_NAME "Freg"
#define MODULE_AUTHOR "wuxiaoer@gmail.com"

/**
 * 设备打开和关闭接口
 */

static int freg_device_open(const struct hw_module_t *module, const char *id, struct hw_device_t **device);
static int freg_device_close(struct hw_device_t *device);

/**
 * 设备寄存器读写接口
 */
static int freg_get_val(struct freg_device_t *dev, int *val);
static int freg_set_val(struct freg_device_t *dev, int val);

/**
 * 定义模块操作方法结构体变量
 */
static struct hw_module_methods_t freg_module_methods = {
    .open = freg_device_open,
};

/**
 * 定义模块结构体变量
 */
struct freg_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .version_major = 1,
        .version_minor = 0,
        .id = FREG_HARDWARE_MODULE_ID,
        .name = MODULE_NAME,
        .author = MODULE_AUTHOR,
        .methods = &freg_module_methods,
    }
};

static int freg_device_open(const struct hw_module_t *module, const char *id, struct hw_device_t **device)
{
    if (!strcmp(id, FREG_HARDWARE_DEVICE_ID))
    {
        struct freg_device_t *dev;

        dev = (struct freg_device_t*)malloc(sizeof(struct freg_device_t));
        if (!dev)
        {
            ALOGE("Failed to alloc space for freg_device_t.");
            return -ENOMEM;
        }

        memset(dev, 0, sizeof(struct freg_device_t));

        dev->common.tag = HARDWARE_DEVICE_TAG;
        dev->common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
        dev->common.module = (hw_module_t*)module;
        dev->common.close = freg_device_close;
        dev->set_val = freg_set_val;
        dev->get_val = freg_get_val;

        if ((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1)
        {
            ALOGE("Failed to open device file /dev/freg -- %s.", strerror(errno));
            free(dev);
            return -EFAULT;
        }else
        {
            ALOGE("Open device file /dev/freg successfully.");
        }

       // *device = &(dev->common);
        *device = (hw_device_t*)dev;

        return 0;
    }

    return -EFAULT;
}

static int freg_device_close(struct hw_device_t *device)
{
    struct freg_device_t *freg_device = (struct freg_device_t*)device;
    if (freg_device)
    {
        close(freg_device->fd);
        free(freg_device);
    }

    return 0;
}

static int freg_get_val(struct freg_device_t *dev, int *val)
{
    if (!dev)
    {
        ALOGE("Null dev pointer");
        return -EFAULT;
    }

    if (!val)
    {
        ALOGE("Null val pointer");
        return -EFAULT;
    }

    read(dev->fd, val, sizeof(*val));

    ALOGI("Get value %d from device file /dev/freg.", *val);

    return 0;
}

static int freg_set_val(struct freg_device_t *dev, int val)
{
    if (!dev)
    {
        ALOGE("Null dev pointer");
        return -EFAULT;
    }

    ALOGI("Set value %d to device file /dev/freg.", val);
    write(dev->fd, &val, sizeof(val));

    return 0;
}

Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := freg.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := freg.cpp
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_MODULE_TAGS := optional
#LOCAL_CFLAGS := -Wno-unused-parameter


include $(BUILD_SHARED_LIBRARY)

$ mmm ./hardware/libhardware/modules/freg/
然后通过如下命令打包生成的.so文件

$ make snod

通过adb shell查看是否生成.so文件



参考

1. 《Android系统源代码情景分析》第2.3节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值