android的HAL第一种调用hal方法中的HAL代码的实现:

来源:互联网 发布:mac os x 10.13 cdr 编辑:程序博客网 时间:2024/06/12 01:32
 下面分析第一种方法中,各层的关键代码。
(1)HAL层
    一般来说HAL moudle需要涉及的是三个关键结构体:
     struct hw_module_t;
     struct hw_module_methods_t;
     struct hw_device_t;
    下面结合代码说明这3个结构的用法。部分代码经过修改,后面的章节会给出修改的原因。
     文件:mokoid-read-only/hardware/modules/include/mokoid/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  
文件:mokoid-read-only/hardware/modules/led/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 "../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 */  
};