两个与hal有关的结构体 hw_module_t ,hw_device_t

wKioL1OdnwHhhqtaAAJyyuX6_Ig195.jpg


一、jni和hal之间的关系

    Tip:几种app,jni,hal,framework之间的关系框架

9b7935a1-70ee-46de-a041-27b457259b43.jpg    这篇文章用的框架是第二种框架的编写,他们的关系如下;

    可以看出jni主要通过pModule和pdevice来获取hal中的变量来操作hal层

feffb976-ff92-4b54-b9e5-a516bbea88ce.jpg

二、jni操作hal

    获取hal层:1、jni获取hal层的module和device对象

wKiom1OdnRWSqp97AAIS2EBu2Ms194.jpg

    操作hal:2、jni操作hal层 

wKioL1OdnfCAMozZAACDnE7uZxY132.jpg

wKiom1Odnh6A27x6AAB0TUBM3XA714.jpg

wKioL1OdnfCAMfp_AAB5H95wXpg587.jpg

jni操作hal完整代码参考[android底层]jni中获取自定义的类函数编写    来对比

三、hal的编写

编写hal注意点(注释部分)

1、HAL的.h文件的编写,自己的硬件自定义的modules和device的编写;以led为例子55541905-052a-4490-84e2-37770b5dca1a.png

2、HAL的.c文件的编写的步骤

编写hal的两个核心

    一个结构体hw_module_t的结构体

    8c84b207-21b3-4e22-985f-3bc8e49415ed.png

    一个hw_module_methods_t中的open函数;

104c0a85-815e-488c-9bfa-1d69ef768f8d.png


hal编写步骤

第一步:hal一切从HMI开始

b7dfd804-377b-43ac-b914-502d8e113f4e.png

第二步:

a80f433f-e484-4cb2-85e3-832e6425837a.png

第三步: 实现jni获取设备(hw_device_t)操作的函数

d1adfde3-2cde-4e63-bbcf-798bf5addfea.png

四、实现jni调用的释放(free)设备(hw_device_t)的函数,与第三步意图相反

3f6f0f48-110f-45c8-8f7c-9805735bdf9b.png


805503d4-95ca-4179-844f-a34536cfa414.png

a9661b87-f2be-401d-bfde-5d6267e6b3c0.jpg



完整代码

hal_led.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef __HAL_LED_H__ 
#define __HAL_LED_H__ 
#include <hardware/hardware.h> 
  
#define LED_MODULE_ID "myled_hal" //目标文件名称: libhal_jni_test.so 
struct  led_hal_modules{ 
     struct  hw_module_t common; //必须这个名称(约定) 
}; 
struct  led_hal_device{ 
     struct  hw_device_t common; //必须这个名称(约定) 
     //下面是设备相关自定义函数 
     int  (*open)(); 
     int  (*ledoff)(); 
     int  (*ledon)(); 
}; 
  
#endif

hal_led.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#define LOG_TAG "myled_hal" 
  
#include <stdlib.h> 
#include "hal_led.h" 
#include <hardware/hardware.h> 
#include <cutils/log.h> 
  
/* 4、实现hw_device_t中的close函数来关闭设备, 
与hw_module_methods_t中的open相反; 
     ps:函数原型int (*close)(struct hw_device_t* device);*/ 
int   mydev_close( struct  hw_device_t* device){ 
     struct  led_hal_device* tmp; 
     if (device != NULL){ 
     tmp = ( struct  led_hal_device*)device; 
     free (tmp); 
    
     return  0; 
  
// 5、实现led_hal_device的自定义函数 
int  mydev_open(){ 
     //open(/dev/leds1, flags); 
     return  0; 
int  ledoff(){ 
     //val = 1; 
     //write(fd, &val, 4); 
     return  0; 
int  ledon(){ 
     //val =0; 
     //write(fd, &val, 4); 
     return  0; 
  
  
     // 3、通过open来分配并返回hw_device_t 给jni调用操作 
int  myled_hal_open( const  struct  hw_module_t* module,  const  char * id, 
struct  hw_device_t** device){ 
     // 3.1、分配一个hw_device_t空间 
     struct  led_hal_device *mydev = ( struct  led_hal_device *) malloc ( sizeof ( struct  led_hal_device *)); 
  
     if (mydev == NULL){ 
     LOGE( "malloc error" ); 
     exit (1); 
    
  
     mydev->common.tag = HARDWARE_DEVICE_TAG; 
     mydev->common.module = module; 
     mydev->common.version = 1; 
  
     //参照第4 步,hw_device_t中的close函数来关闭设备 
     mydev->common.close = mydev_close; 
  
     //led_hal_device自定义函数 
     mydev->open = mydev_open; 
     mydev->ledoff = ledoff; 
     mydev->ledon = ledon; 
  
     // 3.2、向jni传递device对象给jni调用操作
     // 6、记得第三步的3.2步骤中 在open函数中向jni返回hw_device_t 
     *device = (  struct  hw_device_t*)mydev; 
  
     return  0; 
    
  
  
/*    2、本结构体主要作用使得jni通过open(.., .., 
     struct hw_device_t** device)的device来获取hw_device_t 设备*/ 
static  struct  hw_module_methods_t myled_module_methods= { 
     open:myled_hal_open //参照第3 步 
}; 
  
     // 1、结构体名称必须是这样HMI 
struct  led_hal_modules HMI = { 
         common:{ 
             tag: HARDWARE_MODULE_TAG, //tag必须这个 
             version_major: 1, //主设备版本 
             version_minor: 0, //次设备的版本 
             id: LED_MODULE_ID, //.so动态库的名称(char *型) 
             name:  "Graphics Memory Allocator Module" ,
             author:  "The Android Open Source Project" ,
             methods: &myled_module_methods, //hw_module_methods_t,参见第2 步 
         }, 
          
};

Android.mk

1
2
3
4
5
6
7
8
9
10
11
LOCAL_PATH:= $(call my- dir )
include $(CLEAR_VARS)
 
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) /hw
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= myled_hal.default
LOCAL_SRC_FILES:= \
     hal_led.c
LOCAL_SHARED_LIBRARIES := \
     libutils
include $(BUILD_SHARED_LIBRARY)

本文转自lilin9105 51CTO博客,原文链接:http://blog.51cto.com/7071976/1426717,如需转载请自行联系原作者