• 从Android 应用程序到Android Framework层到Android JNI层再到HAL层


    Agenda:

    首先做一个简单的概述:

    Android 为什么要有HAL层?为什么不能将这层接口写在内核空间中?

    我们知道,Linux内核源代码版权遵循GNU License,而Android源代码版权遵循Apache License,前者在发布产品时,必须公布源代码,而后者无须发布源代码。那么假如把HAL层和内核层整合在一起,就必须公开,这样就会损害厂家的利益,因为功能上的逻辑可是代表着这个公司的核心技术。所以就有了HAL层,这一层主要是功能上的逻辑实现,运行在用户空间。

    下面是与硬件抽象层相关的各个层的关系:

    首先在驱动上对硬件直接进行操作,但是这些操作都是最基本的,例如读写寄存器等等。而在HAL层是程序员为了实现一个特定功能,设计编写具体的操作逻辑。在HAL层是c代码,JNI层通过封装HAL层的接口为上层提供接口。

    HAL 层具体介绍:

    /hardware/libhardware/include/hardware$ vi hello.h

    这里面的代码为:

    #ifndef ANDROID_HELLO_INTERFACE_H  
    #define ANDROID_HELLO_INTERFACE_H  
    #include <hardware/hardware.h>  
      
    __BEGIN_DECLS  
      
    /*定义模块ID*/  
    #define HELLO_HARDWARE_MODULE_ID "hello"  
      
    /*硬件模块结构体*/  
    struct hello_module_t {  
        struct hw_module_t common;  
    };  
      
    /*硬件接口结构体*/  
    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);  
    };  
      
    __END_DECLS  
      
    #endif 

    首先介绍代码结构:HAL层代码一般放在hardware/libhardware中,这里我们假设内核中有个hello.so驱动模块,相应的在HAL层定义hal层模块为hello.default.so。

    hello.h 里面按照Android硬件抽象层规范的要求,分别定义模块ID、模块结构体以及硬件接口结构体。

    进入到hardware/libhardware/modules目录,新建hello目录,并添加hello.c文件。 hello.c的内容较多,我们分段来看。

    首先是包含相关头文件和定义相关结构:

    #define LOG_TAG "HelloStub"  
      
    #include <hardware/hardware.h>  
    #include <hardware/hello.h>  
    #include <fcntl.h>  
    #include <errno.h>  
    #include <cutils/log.h>  
    #include <cutils/atomic.h>  
      
    #define DEVICE_NAME "/dev/hello"  
    #define MODULE_NAME "Hello"  
    #define MODULE_AUTHOR "shyluo@gmail.com"  
      
    /*设备打开和关闭接口*/  
    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  
    };  
      
    /*模块实例变量*/  
    struct hello_module_t HAL_MODULE_INFO_SYM = {  
        common: {  
            tag: HARDWARE_MODULE_TAG,  
            version_major: 1,  
            version_minor: 0,  
            id: HELLO_HARDWARE_MODULE_ID,  
            name: MODULE_NAME,  
            author: MODULE_AUTHOR,  
            methods: &hello_module_methods,  
        }  
    };
        static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {  
            struct hello_device_t* dev;dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t));  
              
            if(!dev) {  
                LOGE("Hello Stub: failed to alloc space");  
                return -EFAULT;  
            }  
          
            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;  
          
            if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {  
                LOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);  
                return -EFAULT;  
            }  
          
            *device = &(dev->common);  
            LOGI("Hello Stub: open /dev/hello successfully.");  
          
            return 0;  
        }  
    
    
    
     
  • 相关阅读:
    微信小程序开发——修改小程序原生checkbox、radio默认样式
    微信小程序开发——微信小程序下拉刷新真机无法弹回
    转:slf4j-api、slf4j-log4j12、log4j之间关系
    MyBatis3 入门学习指南
    Java 多线程重排序的探究
    Kafka 生产者和消费者入门代码基础
    Java面试题
    刻苦读书的故事合集
    Win10 calc.exe 无法打开计算器的解决方法
    Redis(三):set/get 命令源码解析
  • 原文地址:https://www.cnblogs.com/alexjie/p/3548047.html
Copyright © 2020-2023  润新知