Android架构实例分析之编写hello驱动的HAL层代码
来源:互联网 发布:koala for mac 编辑:程序博客网 时间:2024/06/05 07:38
Android架构实例分析之编写hello驱动的HAL层代码
摘要:
HAL层中文名称又叫硬件抽象层,可以理解我Linux驱动的应用层。本文实现了一个简单的hello HAL的代码,衔接hello驱动和hello JNI:
http://blog.csdn.net/eliot_shao/article/details/51860229
Android标准架构实例分析之编写最简单的hello驱动
HAL层的代码会使用open read write等系统调用操作驱动层的文件系统(dev、sysfs、proc),同时它也有自己的数据结构,为上层提供接口,并导出和本体模块相关ID号。上层可以使用hw_get_module获得HAL中写的方法。其实如果不是为了避开Linux的GPL开源协议,HAL层可以不用,直接使用JNI层或者在Java代码中访问操作驱动层的文件系统(dev、sysfs、proc)也是可行的。
详细原理可以参考:
http://blog.csdn.net/eliot_shao/article/details/50461738
HAL代码编写的基本步骤
1、编写HAL层头文件
2、填充相关的结构体
1、编写HAL层头文件
首先我们要知道关于HAL的三点要求:
1、 每一个hardware硬件模块都有一个ID;
2、 每一个hardware模块必须有一个继承struct hw_module_t common;的结构体;
3、 每一个hardware模块必须有一个继承struct hw_device_t common;的结构体;
struct hw_module_t的继承者担负了“联络员”的任务,在/system/lib/hw下面有若干hardware module,本地框架层通过ID找到对应的模块。
struct hw_device_t的继承者承担了对驱动操作方法的包装的任务。
struct hw_module_t和struct hw_device_t的内容定义在:
hardware\libhardware\include\hardware\hardware.h
所以我们的hello.h内容如下:
#ifndef ANDROID_HELLO_INTERFACE_H#define ANDROID_HELLO_INTERFACE_H#include <hardware/hardware.h>__BEGIN_DECLS#define HELLO_HARDWARE_MODULE_ID "hello"//IDstruct hello_module_t { struct hw_module_t common;};//hw_module_t的继承者struct hello_device_t { struct hw_device_t common; int fd; int (*set_val)(struct hello_device_t* dev, int val); int (*get_val)(struct hello_device_t* dev, int* val);};//hw_device_t的继承者__END_DECLS#endif
2、填充相关的结构体
我们总结一下硬件具体的调用流程,也是hardware层的工作流程:
1、 通过ID找到硬件模块,struct hw_module_t common的结构体的继承者;
2、 通过硬件模块找到hw_module_methods_t,打开操作,获得设备的hw_device_t;
3、 调用hw_device_t中的各种操作硬件的方法;
4、 调用完成,通过hw_device_t的close关闭设备。
HAL规定了需要创一个名为HAL_MODULE_INFO_SYM结构体,如下:
struct hello_module_t HAL_MODULE_INFO_SYM = { .common = { .tag= HARDWARE_MODULE_TAG, //.module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0, .hal_api_version= HARDWARE_HAL_API_VERSION, .id = HELLO_HARDWARE_MODULE_ID, .name = "Demo shaomingliang hello HAL", .author = "The Android Open Source Project", .methods= &hello_module_methods, },};
填充struct hw_module_t common 并对其成员 methods进行赋值:
.methods= &hello_module_methods,
hello_module_methods的定义如下:
static struct hw_module_methods_t hello_module_methods = { .open = hello_device_open,};
在 hello_device_open
对 struct hello_device_t
进行填充。
下面是抽象层hello.c的详细代码:
#define LOG_TAG "HelloStub"#include <hardware/hardware.h>#include <hardware/hello.h>#include <sys/mman.h>#include <dlfcn.h>#include <cutils/ashmem.h>#include <cutils/log.h>#include <fcntl.h>#include <errno.h>#include <sys/ioctl.h>#include <string.h>#include <stdlib.h>#include <cutils/log.h>#include <cutils/atomic.h>#define MODULE_NAME "Hello"char const * const device_name = "/dev/hello" ;static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);static int hello_device_close(struct hw_device_t* device);static int hello_set_val(struct hello_device_t* dev, int val);static int hello_get_val(struct hello_device_t* dev, int* val);static struct hw_module_methods_t hello_module_methods = { .open = hello_device_open,};static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device){ struct hello_device_t* dev; char name_[64]; //pthread_mutex_t lock; dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t)); if(!dev) { ALOGE("Hello Stub: failed to alloc space"); return -EFAULT; } ALOGE("Hello Stub: hello_device_open eliot_shao"); memset(dev, 0, sizeof(struct hello_device_t)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (hw_module_t*)module; dev->common.close = hello_device_close; dev->set_val = hello_set_val; dev->get_val = hello_get_val; //pthread_mutex_lock(&lock); dev->fd = -1 ; snprintf(name_, 64, device_name, 0); dev->fd = open(name_, O_RDWR); if(dev->fd == -1) { ALOGE("Hello Stub:eliot failed to open %s !-- %s.", name_,strerror(errno)); free(dev); return -EFAULT; } //pthread_mutex_unlock(&lock); *device = &(dev->common); ALOGI("Hello Stub: open HAL hello successfully."); return 0;}static int hello_device_close(struct hw_device_t* device) { struct hello_device_t* hello_device = (struct hello_device_t*)device; if(hello_device) { close(hello_device->fd); free(hello_device); } return 0;}static int hello_set_val(struct hello_device_t* dev, int val) { ALOGI("Hello Stub: set value to device."); write(dev->fd, &val, sizeof(val)); return 0;}static int hello_get_val(struct hello_device_t* dev, int* val) { if(!val) { ALOGE("Hello Stub: error val pointer"); return -EFAULT; } read(dev->fd, val, sizeof(*val)); ALOGI("Hello Stub: get value from device"); return 0;}struct hello_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, //.module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = HELLO_HARDWARE_MODULE_ID, .name = "Demo shaomingliang hello HAL", .author = "The Android Open Source Project", .methods = &hello_module_methods, },};
Android.mk 的详细代码如下:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello.defaultLOCAL_MODULE_RELATIVE_PATH := hwLOCAL_SRC_FILES := hello.cLOCAL_SHARED_LIBRARIES := liblogLOCAL_MODULE_TAGS := optionalinclude $(BUILD_SHARED_LIBRARY)
hello HAL代码的编译
将hal的代码放到如下位置:
hardware\libhardware\modules\hello\hello.c
hardware\libhardware\modules\hello\Android.mk
hardware\libhardware\include\hardware\hello.h
执行:mmm hardware\libhardware\modules\hello\
将会在system/lib/hw/下生成一个hello.default.so!
- Android架构实例分析之编写hello驱动的HAL层代码
- Android标准架构实例分析之编写最简单的hello驱动
- Android架构实例分析之编写hello驱动的系统硬件服务
- Android架构实例分析之注册hello HAL的JNI方法表
- (OK) Android架构实例分析之注册hello HAL的JNI方法表
- Android架构分析之硬件抽象层(HAL)
- Android架构分析之硬件抽象层(HAL)
- Android架构分析之硬件抽象层(HAL)
- android HAL层驱动对接实例
- android TIF HAL层代码分析
- Android应用层到Framework到HAL再到驱动层的整个流程分析
- android HAL层代码
- Android HAL层分析
- Android架构分析之使用自定义硬件抽象层(HAL)模块
- <6>Android HAL 架构分析之硬件抽象层 hardware.h haraware.c sensors.c
- 编写android HAL代码
- android关于GPS hal层的分析
- android关于GPS hal层的分析
- Android5.x之RecyclerView使用(5)网格布局
- leetcode Median Of Two Sorted Arrays
- 用libevent实现httpserver
- 如何排查并解决SEAndroid 的审计不通过
- 【leetcode】278. First Bad Version
- Android架构实例分析之编写hello驱动的HAL层代码
- 切换场景的动画
- Just a Html
- 时间空间
- 小数值1.5625的二进制表示是?----阿里巴巴2015实习生笔试题
- django render和render_to_response()
- HashMap以及跟HashMap相关的内容
- linux 内存调优
- PHP 里面session_unset()函数与session_destroy()函数比较