HAL例程

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 */  
};  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘭噗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值