1、简单的HAL最小驱动,用于熟悉架构
(1)hal_test.h
#ifndef HAL_TEST_H
#define HAL_TEST_H
#include <hardware/hardware.h>
#include <hardware/fb.h>
__BEGIN_DECLS //C与c++兼容的宏定义
#define HAL_TEST_HARDWARE_MODULE_ID "HAL_TEST" //定义一个模块ID
#define HAL_TEST_HARDWARE_GPU0 "HAL_TEST" //定义device名,用于查找指定的device
typedef struct hal_test_module_t { //模块结构体
struct hw_module_t common; //hardware module 结构体,用于操作指定模块
}
typedef struct hal_test_device_t { //设备结构体
struct hw_device_t common; //hardware device 结构体,用于操作指定设备
}
__END_DECLS
#endif
(2)hal_test.cpp
#inclkude <hardware/hal_test.h>
/*device 释放函数,释饭设备资源*/
static int hal_test_close(struct hw_device_t *dev)
{
hal_test_device_t* ctx = reinterpret_cast<gralloc_context_t*>(dev); //获取到hal_test_device_t指针
if (ctx) {
free(ctx); //释放
}
return 0;
}
/*打开指定的设备*/
int hal_test_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
{
int status = -EINVAL;
if (!strcmp(name, HAL_TEST_HARDWARE_GPU0)) { //判断是否是指定的设备,这里可以为模块添加多个设备
hal_test_device_t *dev; //定义一个设备指针
dev = (hal_test_device_t*)malloc(sizeof(*dev)); //为设备指针分配内存
/* initialize our state here */
memset(dev, 0, sizeof(*dev)); //清空内存
/* initialize the procs */
dev->device.common.tag = HARDWARE_DEVICE_TAG; //tag必须为HARDWARE_DEVICE_TAG
dev->device.common.version = 0; //版本为0
dev->device.common.module = const_cast<hw_module_t*>(module); //赋值模块地址
dev->device.common.close = hal_test_close; //赋值释放函数指针
*device = &dev->device.common; //把hw_device_t赋值给device,返回值
status = 0;
}
return 0;
}
/*hw_module_methods_t 的 open 函数指针赋值 ,用于打开指定设备 */
static struct hw_module_methods_t hal_test_module_methods = {
.open = hal_test_device_open
};
/*模块结构体*/
struct private_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG, //tag必须为HARDWARE_MODULE_TAG
.version_major = 1, //主版本号
.version_minor = 0, //次版本号
.id = HAL_TEST_HARDWARE_MODULE_ID, //模块ID
.name = "Graphics Memory Allocator Module", //模块名
.author = "The Android Open Source Project", //模块作者
.methods = &hal_test_module_methods //模块的hw_module_methods_t,也就是open所在的结构体指针
},
};
2、LED HAL驱动
(1) led.h
/***************************************************************************/
struct led_module_t {
struct hw_module_t common;
};
//HAL 规定不能直接使用hw_module_t结构,因此需要做这么一个继承。
struct led_control_device_t {
//自定义的一个针对Led控制的结构,包含hw_device_t和支持的API操作
struct hw_device_t common;
/* attributes */
int fd; //可用于具体的设备描述符
/* supporting control APIs go here */
int (*set_on)(struct led_control_device_t *dev, int32_t led);
int (*set_off)(struct led_control_device_t *dev, int32_t led);
};
#define LED_HARDWARE_MODULE_ID "led"
//定义一个MODULE_ID,HAL层可以根据这个ID找到我们这个HAL stub
(2) led.c
#define LOG_TAG "MokoidLedStub"
#include <hardware/hardware.h>
#include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
//#include <mokoid/led.h>
#include "../include/mokoid/led.h"
/*****************************************************************************/
int fd; //硬件led的设备描述符 。你也可以用led_control_device_t结构中定义的fd
#define GPG3DAT2_ON 0x4800 //ioctl控制命令
#define GPG3DAT2_OFF 0x4801
int led_device_close(struct hw_device_t* device)
{
struct led_control_device_t* ctx = (struct led_control_device_t*)device;
if (ctx) {
free(ctx);
}
close(fd);
return 0;
}
int led_on(struct led_control_device_t *dev, int32_t led)
{
LOGI("LED Stub: set %d on.", led);
ioctl(fd,GPG3DAT2_ON,NULL); //控制Led亮灭,和硬件相关
return 0;
}
int led_off(struct led_control_device_t *dev, int32_t led)
{
LOGI("LED Stub: set %d off.", led);
return 0;
}
static int led_device_open(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
struct led_control_device_t *dev;
dev = (struct led_control_device_t *)malloc(sizeof(*dev));
memset(dev, 0, sizeof(*dev));
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = module;
dev->common.close = led_device_close;
dev->set_on = led_on; //实例化支持的操作
dev->set_off = led_off;
*device = &dev->common; //将实例化后的led_control_device_t地址返回给jni层
//这样jni层就可以直接调用led_on、led_off、led_device_close方法了。
if((fd=open("/dev/led",O_RDWR))==-1) //打开硬件设备
{
LOGE("LED open error");
}
else
LOGI("open ok");
success:
return 0;
}
static struct hw_module_methods_t led_module_methods = {
open: led_device_open
};
const struct led_module_t HAL_MODULE_INFO_SYM = {
//定义这个对象等于向系统注册了一个ID为LED_HARDWARE_MODULE_ID的stub。注意这里HAL_MODULE_INFO_SYM的名称不能改。
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: LED_HARDWARE_MODULE_ID,
name: "Sample LED Stub",
author: "The Mokoid Open Source Project",
methods: &led_module_methods, //实现了一个open的方法供jni层调用,
//从而实例化led_control_device_t
}
/* supporting APIs go here */
};