524
查看hal的源代码
hal
0
←
hal
跳转至:
导航
、
搜索
因为以下原因,你没有权限编辑本页:
你被禁止执行你刚才请求的操作。
您可以查看并复制此页面的源代码:
== 三个重要结构体 == *hw_module_t <pre class="prettyprint"> /** * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM * and the fields of this data structure must begin with hw_module_t * followed by module specific information. */ typedef struct hw_module_t { /** tag must be initialized to HARDWARE_MODULE_TAG */ uint32_t tag; /** major version number for the module */ uint16_t version_major; /** minor version number of the module */ uint16_t version_minor; /** Identifier of module */ const char *id; /** Name of this module */ const char *name; /** Author/owner/implementor of the module */ const char *author; /** Modules methods */ //模块方法列表,指向hw_module_methods_t* struct hw_module_methods_t* methods; /** module's dso */ void* dso; /** padding to 128 bytes, reserved for future use */ uint32_t reserved[32-7]; } hw_module_t; </pre> *hw_module_methods_t <pre class="prettyprint"> typedef struct hw_module_methods_t { //硬件模块方法列表的定义,这里只定义了一个open函数 /** Open a specific device */ int (*open)(const struct hw_module_t* module, const char* id, struct hw_device_t** device); } hw_module_methods_t; </pre> *hw_device_t <pre class="prettyprint"> /** * Every device data structure must begin with hw_device_t * followed by module specific public methods and attributes. */ typedef struct hw_device_t { /** tag must be initialized to HARDWARE_DEVICE_TAG */ uint32_t tag; /** version number for hw_device_t */ uint32_t version; /** reference to the module this device belongs to */ struct hw_module_t* module; /** padding reserved for future use */ uint32_t reserved[12]; /** Close this device */ int (*close)(struct hw_device_t* device); } hw_device_t; </pre> == 定义自己的hal模块 == === 一、在.h文件中“继承”hw_module_t、hw_device_t === <pre class="prettyprint"> //led.h /* HAL规定不能直接使用hw_module_t结构,因此需要做这么一个继承 */ struct led_module_t { struct hw_module_t common; }; struct led_control_device_t { /* 自定义的一个针对Led控制的结构,包含hw_device_t和支持的API操作 */ struct hw_device_t common; /*可用于具体的设备描述符,如指向/dev/xxx */ int fd; /* 在这里定义自己的控制api */ int (*set_on)(struct led_control_device_t *dev, int32_t led); int (*set_off)(struct led_control_device_t *dev, int32_t led); }; /* 定义一个MODULE_ID,HAL层可以根据这个ID找到我们这个HAL stub */ #define LED_HARDWARE_MODULE_ID "led" </pre> === 二、.c文件中定义相关变量、实现相关函数 === 1、定义相关变量 由本文件第一节“三个重要的结构体”可知,hw_device_t包含hw_module_t类型指针,hw_module_t包含hw_module_methods_t类型指针,而上面.h头文件我们自定义的led_control_device_t结构体又包含hw_device_t结构体,因此这四个结构体的复用情况如下: hw_module_methods_t <- hw_module_t <- hw_device_t <- led_control_device_t 也就是说,通过led_control_device_t我们可以找到hal三大结构体类型(变量),而上一小节的代码中也说明了我们自定义的一些控制api也是放在led_control_device_t中的。 因此自然而然,我们应该很容易想到我们应该首先定义一个led_control_device_t变量: <pre class="prettyprint"> //led.c 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, //这里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 } }; </pre> 从上面可以看出,实际并不是这样的,这里并没有定义led_control_device_t变量,却定义了led_module_t变量,而这个函数仅包括了一个hw_module_methods_t类型指针,而hw_module_methods_t中却只有一个open函数,那其他接口函数是如何传给jni的呢? 其实,关键也就在于这个open函数(可以先查看下一节的led_device_open函数),正是通过这个函数将hw_device_t类型指针返回给上层jni的,而在led_control_device_t结构体中,hw_device_t类型指针是第一个变量(规范要求必须为第一个变量),如此在jni上通过将hw_device_t类型指针的强制转换为led_control_device_t类型,则完成了接口函数的传递过程。 如果对这个感兴趣的话可以参阅下这篇文章:[http://blog.csdn.net/flydream0/article/details/7086273 Android中HAL如何向上层提供接口总结] 2、定义相关函数 有哪些函数需要定义呢?我们先来统计一下,我们按照以下“包含”关系自底向上来进行统计: hw_module_methods_t <- hw_module_t <- hw_device_t <- led_control_device_t (1)hw_module_methods_t中的<span style="color:#FF0000;">open</span>函数; (2)hw_module_t中无; (3)hw_device_t中的<span style="color:#FF0000;">close</span>函数; (4)led_control_device_t中自定义的<span style="color:#FF0000;">api函数</span>; 统计是准确的: <pre class="prettyprint"> //led.c 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); } return 0; } int led_on(struct led_control_device_t *dev, int32_t led) { LOGI("LED Stub: set %d on.", 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; success: return 0; } </pre> == 思考 == 为什么hal在往上传接口时要以hw_module_t类型给出,然后在jni中对指针进行强制转换,而不直接以用户定义的类型(如led_control_device_t)传出? 参考资料: [http://blog.csdn.net/hongtao_liu/article/details/6060734 Android HAL实例解析-刘洪涛的专栏] [http://blog.csdn.net/flydream0/article/details/7086273 Android中HAL如何向上层提供接口总结] 注: 本文引用的是台湾的Jollen的[http://mokoid.googlecode.com/svn/trunk/ mokoid]工程代码
返回
hal
。
导航菜单
个人工具
   
个人维基
注册
登录
名字空间
页面
变换
查看
阅读
查看源代码
统计
查看历史
操作
搜索
导航
首页
Ubuntu
Android
C&CPP
Java
Python
大杂烩
最近更改
工具箱
所有页面
文件列表
特殊页面