安卓进阶三:硬件抽象层HAL之开发硬件抽象层模块

        本文是学习罗升阳的《安卓系统源代码情景分析》的笔记和总结

        感觉这块主要就是要理解hw_module、hw_module_methods_t、hw_device之间的关系。

        思路:hw_module主要是通过hw_module_mehtods_t根据具体的device id打开具体的hw_device,其中hw_device是对底层的驱动文件的抽象,hw_device里面可以自定义一些方法来对底层驱动进行操作,这样一来,在用户空间操作hw_device就相当于操作了内核空间的底层驱动,形成这样的调用关系hw_module---->hw_device----->底层驱动,注意hw_device由hw_module打开,关闭的方法则是自带的,关系图如下:

代码的具体位置和老罗的没区别,主要是头文件改动了些,然后device的名字等也有改变

hardware/libhardware/include/hardware/freg.h

#ifndef ANDROID_FREG_INTERFACE_H
#define ANDROID_FREG_INTERFACE_H
#include <hardware/hardware.h>

__BEGIN_DECLS

/*第一步:自定义模块和设备结构体
*
*类似于java里面的新建一个类(比如这里的freg_module_t)继承某个类(比如
*这里的hw_module_t),只不过在c中没有继承这一说法,所以采用结构体包含
*结构体的方法实现
*/

struct freg_module_t {
	struct hw_module_t moduleBase;
};

struct freg_device_t{
	struct hw_device_t deviceBase;
	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

hardware/libhardware/modules/freg/freg.cpp

#define LOG_TAG "FregStub"

#include <hardware/hardware.h>
#include <hardware/freg.h>
#include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>



#define FREG_MODULE_NAME "Freg"
#define FREG_MODULE_ID "freg_module"

#define FREG_DEVICE_NAME "/dev/myfreg"
#define FREG_DEVICE_ID "freg_device"


/*设备打开、关闭函数*/
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_set_val (struct freg_device_t * dev ,int val );
static int freg_get_val (struct freg_device_t * dev , int * val);


/*模块操作方法结构体变量,就是通过open成员方法把module和device联系起来的*/
static struct hw_module_methods_t module_methods ={
	open : freg_device_open
};


/*这里类似于java中的创建一个类的对象并初始化*/
struct freg_module_t HAL_MODULE_INFO_SYM ={
	moduleBase : {
		tag : HARDWARE_MODULE_TAG,
		version_major : 1,
		version_minor : 0,
		id : FREG_MODULE_ID,
		name : FREG_MODULE_NAME,
		author: "wanglx", //不初始化会报错
		methods : &module_methods,
		dso : NULL, //不初始化会报错
		reserved :{0} , //不初始化会报错
	}
};


static int freg_device_open (const struct hw_module_t* module, const char* id,
            struct hw_device_t** device)
{
	if(!strcmp(id,FREG_DEVICE_ID))
	{
			
			//初始化device
			struct freg_device_t * dev;
			dev=(struct freg_device_t *)malloc(sizeof(struct freg_device_t));
			if(!dev){
				LOGE("Failed to alloc space for freg_device_t");
				return -EFAULT;
			}

			memset(dev,0,sizeof(struct freg_device_t));
			dev->deviceBase.tag =HARDWARE_DEVICE_TAG;
			dev->deviceBase.version=0;
			dev->deviceBase.module =(hw_module_t *)module;
			dev->deviceBase.close= freg_device_close;
			dev->get_val = freg_get_val;
			dev->set_val =freg_set_val ;

			if((dev->fd =open(FREG_DEVICE_NAME,O_RDWR))==-1){
				LOGE("Failed to open freg_device");
				free(dev);
			return -EFAULT;
			}

			*device =&(dev->deviceBase);
			LOGE("success to open freg_device");
			return 0;
	}
	return -EFAULT;

}


static int freg_device_close (struct hw_device_t* device)
{
	//这里传入hw_device_t的指针类型,下面再进行强制类型转化增加了这个函数的复用性
	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_set_val (struct freg_device_t * dev ,int val )
{
	
	if(!dev){
		LOGE("Null dev pointer");
		return -EFAULT;
	}

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

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

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

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



Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := freg.cpp
#注意这里的名字是freg_module,也就是MODULE_ID
LOCAL_MODULE := freg_module.default
include $(BUILD_SHARED_LIBRARY)

这里要主要mk文件里面MODULE的名字要和MODULE_ID对应

结果:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值