HAL -- (3)增加硬件抽象层(HAL)模块访问内核驱动程序
简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中。在这一篇文章中,我们将继续介绍Android系统硬件驱动程序的另一方面实现,即如何在硬件抽象层中增加硬件模块来和内核驱动程序交互。
一:进入 ics/hardware/libhardware目录中创建 zhx_print目录
android/ics$ cd hardware/libhardware/
ics/hardware/libhardware$ mkdir zhx_print
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
#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"
#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);
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,
};
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,
},
};
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;
}
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;
}
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;
}
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;
}
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)
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文件已经添加进系统里面了!!!
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#
本文详细介绍如何在Android系统中通过硬件抽象层(HAL)增加自定义硬件模块,与内核驱动进行交互。具体步骤包括创建HAL模块目录、编写头文件与源代码、构建HAL模块并集成到系统中。
2261

被折叠的 条评论
为什么被折叠?



