HAL(3) -- 增加硬件抽象层(HAL)模块访问内核驱动程序

HAL -- (3)增加硬件抽象层(HAL)模块访问内核驱动程序

 
在  HAL -- (1):编写android内核驱动 一文中,我们举例子说明了如何在Linux内核编写驱动程序。
简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中。在这一篇文章中,我们将继续介绍Android系统硬件驱动程序的另一方面实现,即如何在硬件抽象层中增加硬件模块来和内核驱动程序交互。
 
一:进入 ics/hardware/libhardware目录中创建 zhx_print目录
 
android/ics$                  cd hardware/libhardware/
ics/hardware/libhardware$     mkdir zhx_print
 
二:进入zhx_print目录中创建 zhx_print.h头文件
 
zhx_print.h
 
#ifndef __ZHX_PRINT_H_
#define __ZHX_PRINT_H_

#include <hardware/hardware.h>

#define ZHX_PRINT_HARDWARE_NAME"zhx_print"

struct print_module_t    
{
    struct hw_module_t common;    //hw_module_t 代表每一个硬件抽象模块 里面hw_module_methods_t
};


struct print_device_t
{
    struct hw_device_t common;    //hw_device_t 代表硬件设备
    int fd;
    int (*set_val)(struct print_device_t*dev,int val);
    int (*get_val)(struct print_device_t*dev,int*val);
};

#endif
 
三:在zhx_print目录中创建zhx_print.c文件
 
zhx_print.c
#include"zhx_print.h"
#include <fcntl.h>

#include <errno.h>
#define LOG_TAG "ZHX_PRINT"
#include <cutils/log.h>
#include <cutils/atomic.h>


#define DEVICE_NAME "/dev/zhx_print"


/*函数声明*/
static int print_device_open(conststruct hw_module_t* module,const char* id,
            struct hw_device_t** device);

static int print_device_close(struct hw_device_t* device);

static int print_device_set_val(struct print_device_t*dev,int val);
static int print_device_get_val(struct print_device_t*dev,int*val);


/*HAL模块方法*/
static struct hw_module_methods_t print_module_methods = 
{
    .open = print_device_open,
};

/*一个HAL模块一定要定义 HAL_MODULE_INFO_SYM!*/
struct print_module_t HAL_MODULE_INFO_SYM= 
{
    common : 
    {
        tag : HARDWARE_MODULE_TAG,
        version_major : 1,
        version_minor : 0,
        id : ZHX_PRINT_HARDWARE_NAME,
        name : ZHX_PRINT_HARDWARE_NAME,
        author : "zheng_he_xiang",
        methods : &print_module_methods, 


    },
};
////////函数实现////////////
/*HAL打开函数*/
static int print_device_open(conststruct hw_module_t* module,const char* id,
            struct hw_device_t** device)
{
    if(!strcmp(id,ZHX_PRINT_HARDWARE_NAME))
    {
        struct print_device_t*dev = NULL;

        /*成功匹配ID*/
        LOGI("hardware : found driver -- sucessfully ");

        //1.分配自定义结构体内存空间
        dev = (struct print_device_t*)malloc(sizeof(struct print_device_t));
        if(dev == NULL)
        {
            LOGI("hardware : dev malloc error\n");
            return -ENOMEM;
        }
        //2.初始化print_device_t结构体成员
        // common
        dev->common.tag= HARDWARE_DEVICE_TAG;
        dev->common.version= 0;
        dev->common.module=(struct hw_module_t*)module;
        dev->common.close= print_device_close;
        // get_val
        dev->get_val= print_device_get_val;
        // set_val
        dev->set_val= print_device_set_val;

        //3.打开内核驱动
        if((dev->fd= open(DEVICE_NAME,O_RDWR)) == -1)
        {
            LOGE("hardware : Failed to open device file /dev/zhx_print.");
            free(dev);
            return -EFAULT;
        }
        //4.把相关结构体保存起来(传递给close函数调用)
        *device =&(dev->common);

        //
        LOGI("hardware : Open device file /dev/zhx_print sucessfully\n");

        return 0;
    }
    else
    {
        LOGE("hardware : i am sorry about that we not found the driver\n");
        return -1;
    }

    return 0;    
}
/*close函数*/
static int print_device_close(struct hw_device_t* device)
{
    struct print_device_t *dev = (struct print_device_t*)device;
    if(dev)
    {
        close(dev->fd);
        free(dev);
    }
    return 0;
}
/*print_device_get_val*/
static int print_device_get_val(struct print_device_t*dev,int*val)
{
    if(!dev)
    {
        LOGE("hardware : NUll dev pointer.");
        return -EFAULT;
    }

    if(!val)
    {
        LOGE("hardware : NUll val pointer.");
        return -EFAULT;
    }


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

    LOGI("hardware : Get value %d from device file /dev/zhx_print",val);

    return 0;
}
/*print_device_set_val*/
static int print_device_set_val(struct print_device_t*dev,int val)
{
    if(!dev)    
    {
        LOGE("hardware : Null dev pointer");
        return -EFAULT;
    }

    LOGI("Set value %d to device file /dev/zhx_print.",val);

    write(dev->fd,&val,sizeof(val));

    return 0;
}
 
四:在zhx_print目录中创建Android.mk文件
 
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS :=optional
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := zhx_print.c
LOCAL_MODULE := zhx_print.default
include $(BUILD_SHARED_LIBRARY)
 
 
五:在zhx_print目录中执行以下命令:
ics/hardware/libhardware/zhx_print$ mm
 
六:在android源码根目录下执行以下命令:
ics$ make snod
到这里,我们就可以在out/target/product/generic/system/lib/hw中得到一个zhx_print.default.so文件了
 
六:在android系统中执行以下命令可以看到:
root@android:/system/lib/hw# ls
ls
audio.a2dp.default.so
audio.primary.default.so
audio.primary.tcc892x.so
audio_policy.default.so
camera.goldfish.so
camera.tcc892x.so
gps.goldfish.so
gps.tcc892x.so
gralloc.default.so
lights.goldfish.so
lights.tcc892x.so
print.default.so
sensors.goldfish.so
sensors.tcc892x.so
zhx_print.default.so
root@android:/system/lib/hw#
到这里,我们可以找到,我们的zhx_print.default.so文件已经添加进系统里面了!!!
 
 
 
 

你可能感兴趣的:(Android,--,HAL层)