HAL
The Android HAL (hardware abstraction layer) Google response to manufacturers "do not wish to open source" requirements, the launch of the new ideas, its structure as shown below. HAL "level of abstraction" insufficient implementation at this stage is not in full compliance with the HAL architecture and planning, but it does give us a good space to think.
Figure 1: Android HAL architecture and planning
Figure 2: Android HAL / libhardware_legacy
Figure 3: Android HAL / libhardware
HAL's future development?
The new HAL practices tendency comprehensive JNI way. That is, in the Android architecture, modify the Android runtime implementation (ie "Core Library"), in the the HAL module operations after a callback operation. HAL module placed inside the HAL. More than I think it should be for framework development. If only hal access to hardware, can not modify the core Library.
, HAL steps:
(1) Java AP initialize a java service Then according to the needs of a combination of call the java service interface.
(2) Java Native Interface Service set statement, And loaded at initialization time Native Service where library Native Service is actually a dynamic link library, JNI and Java Service interaction.
(3) registered by the OnLoad method of Native and Java Service function between the corresponding JNI table.
(4) by HAL Module ID corresponding to the actual board hardware Module This Module HAL interface Open access to hardware device instance. Interface device combining the local implementation of the function.
(5) the preparation of the HAL stub Module and Device instance corresponds to a specific hardware device initialization, API package and hardware drivers.
(6) HAL module to MODULE_ID.platform.so name stored in the file system / system / lib / hw / below.
Android HAL layer in the hardware catalog, hardware / libhardware / is the same with the concept of modules to load the HAL. So library. Here to illustrate the concrete steps to achieve a simple led small example (fake equipment, does not involve the operation of the hardware).
Two, HAL stub to achieve step (Implementation)
Design your own wrapper data structure
* The preparation of header files led.h the
* Define struct led_module_t
* Framework provides the struct hw_module_t of struct hw_device_t must be placed in a field, and the name for the Common.
* Hardware / hardware.h
struct led_module_t {
The struct hw_module_t common;
/ * Support API for LEDServices constructor * /
};
2 led_module_t significance
Notice initialization period (new object) Supporting API in the constructor will be used.
3 Definitions led_control_device_t
Supporting Statement for the control period API Manager API.
struct led_control_device_t {
The struct hw_device_t common;
/ * Supporting control APIs go here * /
int (* getcount_led) (struct led_control_device_t * dev);
int (* set_on) (struct led_control_device_t * dev);
int (* set_off) (struct led_control_device_t * dev);
};
4 Each HAL stub must declare the module ID
The # define LED_HARDWARE_MODULE_ID "led"
5. The statement stub Operations and callback functions
The Stub's module structure must be named HAL_MODULE_INFO_SYM, this name can not be changed.
const struct led_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG
version_major: 1,
version_minor: 0
id: LED_HARDWARE_MODULE_ID
name: "led HAL module",
author: "gggggg",
methods: & led_module_methods,
},
/ * Supporting APIs go here * /
};
The following are the specific contents of the file.
file of led.h:
# Include <hardware/hardware.h>
# Include <fcntl.h>
# Include <errno.h>
# Include <cutils/log.h>
# Include <cutils/atomic.h>
The # define LED_HARDWARE_MODULE_ID "led"
struct led_module_t {
The struct hw_module_t common;
/ * Support API for LEDServices constructor * /
};
struct led_control_device_t {
The struct hw_device_t common;
/ * Supporting control APIs go here * /
int (* getcount_led) (struct led_control_device_t * dev);
int (* set_on) (struct led_control_device_t * dev);
int (* set_off) (struct led_control_device_t * dev);
};
struct led_control_context_t {
struct led_control_device_t device;
};
file of led.c:
# Define LOG_TAG "LedStub"
# Include <hardware/hardware.h>
# Include <fcntl.h>
# Include <errno.h>
# Include <cutils/log.h>
# Include <cutils/atomic.h>
# Include ".. / Include / led.h"
static int led_device_close (struct hw_device_t * device)
{
struct led_control_context_t * ctx = (struct led_control_context_t *) device;
if (ctx) {
free (ctx);
}
return 0;
}
static int led_getcount (struct led_control_device_t * dev)
{
LOGI ("led_getcount);
return 4;
}
static int led_set_on (struct led_control_device_t * dev)
{
/ / FIXME: do system call to control gpio led
LOGI ("led_set_on);
return 0;
}
static int led_set_off (struct led_control_device_t * dev)
{
/ / FIXME: do system call to control gpio led
LOGI ("led_set_off);
return 0;
}
static int led_device_open (const struct hw_module_t * module, const char * name,
the struct hw_device_t ** device)
{
struct led_control_context_t * context;
LOGD ("led_device_open");
context = (struct led_control_context_t *) malloc (sizeof (* context));
memset (context, 0, sizeof (* context));
/ / HAL must init property
context-> device.common.tag = HARDWARE_DEVICE_TAG;
context-> device.common.version = 0;
context-> device.common.module = module;
context-> device.common.close = led_device_close;
/ / Initialize the control API
context-> device.set_on = led_set_on;
context-> device.set_off = led_set_off;
context-> device.getcount_led = led_getcount;
* Device = (struct hw_device_t *) & (context-> device);
return 0;
}
static struct hw_module_methods_t led_module_methods = {
open: led_device_open
};
const struct led_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG
version_major: 1,
version_minor: 0
id: LED_HARDWARE_MODULE_ID
name: "led HAL module",
author: "gggggg",
methods: & led_module_methods,
},
/ * Supporting APIs go here * /
};
The Android.mk document:
LOCAL_PATH: = $ (call my-dir)
include $ (CLEAR_VARS)
LOCAL_PRELINK_MODULE: = false
LOCAL_SHARED_LIBRARIES: = liblog
LOCAL_SRC_FILES: = led.c
LOCAL_MODULE: = led.goldfish
include $ (BUILD_SHARED_LIBRARY)
Third, build a project in Eclipse we write led stub.
Define two classes, the source code is as follows:
File Myhal.java:
The package com.hello.MyHal;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.hello.LedService.LedService;;
public class Myhal extends Activity implements View.OnClickListener {
static LedService led_srv;
static Button btn;
static boolean iflag = false;
/ ** Called when the activity is first created. * /
@ Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.main);
Log.i ("Java App", "OnCreate");
led_srv is = new LedService ();
Log.i ("Java App", "Load Java Serivce");
btn = (Button) this.findViewById (R.id.mybtn);
btn.setOnClickListener (this);
}
public void onClick (View v) {
Log.i ("Java App", "btnOnClicked");
String title = new String ();
if (iflag) {
the title = led_srv.set_off ();
btn.setText ("Turn On");
setTitle (title);
iflag = false;
} Else {
the title = led_srv.set_on ();
btn.setText ("Turn Off");
setTitle (title);
iflag = true;
}
}
}
File LedService.java:
The package com.hello.LedService;
import android.util.Log;
public final class LedService {
/ *
* Load native service.
* /
static {
Log. I ("Java Service", "Load Native Serivce LIB");
System LoadLibrary ("led_runtime");
}
the public LedService () {
int icount;
Log. I ("Java Service", "do init Native Call");
_init ();
icount = _get_count ();
Log. D ("Java Service", "Init OK");
}
/ *
* LED native methods.
* /
the public String SET_ON () {
Log. I ("com.hello.LedService", "LED On");
_set_on ();
return "Led on";
}
public String set_off () {
Log. I ("com.hello.LedService", "LED Off");
_set_off ();
return LED off;
}
/ *
* Declare all the native interface.
* /
private static native boolean _init ();
private static native the int _set_on ();
private static native int _set_off ();
private static native the int _get_count ();
}
Which LedService class native function led stub provided.
(2) Then we realized through the the jni interface implementation native method.
Without using javah generates the appropriate header files.
file of com_hello_LedService.cpp:
# Define LOG_TAG "LedService"
# Include "utils / Log.h"
# Include <stdlib.h>
# Include <string.h>
# Include <unistd.h>
# Include <assert.h>
# Include <jni.h>
# Include ".. /.. / Led_stub / include / led.h"
static led_control_device_t * sLedDevice = 0;
static led_module_t * sLedModule = 0;
of static int The get_count (void)
{
return 0;
}
static jint led_setOn (JNIEnv * env, jobject thiz) {
/ / The if (sLedDevice) {
LOGI ("led_set_on);
sLedDevice-> set_on (sLedDevice);
/ /}
return 0;
}
static jint led_setOff (JNIEnv * env, jobject thiz) {
/ / The if (sLedDevice) {
LOGI ("led_set_off);
sLedDevice-> set_off (sLedDevice);
/ /}
return 0;
}
/ ** Helper APIs * /
static inline int led_control_open (const struct hw_module_t * module,
struct led_control_device_t ** device) {
LOGI ("led_control_ope);
return module-> methods-> open (module,
LED_HARDWARE_MODULE_ID, (struct hw_device_t **) device);
}
static jint led_init (JNIEnv * env, jclass clazz)
{
led_module_t const * module;
LOGI ("led_init);
if (hw_get_module (LED_HARDWARE_MODULE_ID, (const hw_module_t **) & module) == 0) {
LOGI ("get Module OK");
sLedModule = (led_module_t *) module;
if (led_control_open (& module-> common, & sLedDevice)! = 0) {
LOGI ("led_init error");
return -1;
}
}
LOGI ("led_init Success");
return 0;
}
/ *
* Array of methods.
*
* Each entry has three fields: the name of the method, the method
* Signature, and a pointer to the native implementation.
* /
static const JNINativeMethod gMethods [] = {
{"_init" () Z "
(Void *) led_init}
{"_set_on () I
(Void *) led_setOn}
{"_set_off () I
(Void *) led_setOff}
{"_get_count () I
(Void *) The get_count}
};
of static int registerMethods (JNIEnv * env) {
static const char * const kClassName =
"Com / hello / LedService / LedService";
jclass clazz;
/ * Look up the class * /
clazz = env-> FindClass (kClassName);
if (clazz == NULL) {
LOGE ("Can't find class% s / n", kClassName);
return -1;
}
/ * Register all the methods * /
if (env-> RegisterNatives (clazz, gMethods,
sizeof (gMethods) / sizeof (gMethods [0]))! = JNI_OK)
{
LOGE ("Failed registering methods for% s / n", kClassName);
return -1;
}
/ * Fill out the rest of the ID cache * /
return 0;
}
/ *
* This is called by the VM when the shared library is first loaded.
* /
jint JNI_OnLoad (JavaVM * vm, void * reserved) {
JNIEnv * env = NULL;
jint result = -1;
LOGI ("JNI_OnLoad");
if (vm-> GetEnv ((void **) & env, JNI_VERSION_1_4)! = JNI_OK) {
LOGE ("ERROR: GetEnv failed / n");
goto fail;
}
assert (env! = NULL);
the if (registerMethods (env) = 0) {
LOGE ("ERROR: PlatformLibrary native registration failed / n");
goto fail;
}
/ * Success - return valid version number * /
result = JNI_VERSION_1_4;
fail:
return result;
}
The Android.mk document:
LOCAL_PATH: = $ (call my-dir)
include $ (CLEAR_VARS)
# LOCAL_MODULE_TAGS: = eng
# This is the target being built.
LOCAL_MODULE: = libled_runtime
# All of the source files that we will compile.
LOCAL_SRC_FILES: = /
com_hello_LedService.cpp
# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES: = /
libandroid_runtime /
libnativehelper /
libcutils /
libutils /
libhardware
# No static libraries.
LOCAL_STATIC_LIBRARIES: =
# Also need the JNI headers.
LOCAL_C_INCLUDES + = /
$ (JNI_H_INCLUDE)
# No specia compiler flags.
LOCAL_CFLAGS + =
# Do not prelink this library. For more efficient code, you may want
# To add this library to the prelink map and set this to true.
LOCAL_PRELINK_MODULE: = false
include $ (BUILD_SHARED_LIBRARY)
The LED Stub LedService and related files on the development / my_module make to generate the so files. Adb push command to install to a virtual machine can be run.
File organization is as follows:
a @ ubuntu: ~ / work / android / source_android / development / my_module $ pwd
/ Home / a / work / android / source_android / development / my_module
a @ ubuntu: ~ / work / android / source_android / development / my_module $ tree hal
hal
| - LedService
| `- JNI
| | - Android.mk
| `- Com_hello_LedService.cpp
`- Led_stub
| - Include
| `- Led.h
`- Module
| - Android.mk
`- Led.c
6 directories, 7 files
, Compile and run the problems encountered and solutions:
1.usr/bin/ld: cannot find-lz
collect2: ld return 1
Only the library named, simply do a soft link, and you're done
ln-svf / lib/libz.so.1 / lib / libz.so
This library file and soft link named only a .1
2.frameworks/base/tools/aidl/AST.cpp: 10: error: 'fprintf' was not declared in this scope. Mistake
Download gcc-4.3 and g+ + -4.3
apt-get install gcc-4.3 g+ + -4.3
About more than 10 trillion, and then
Enter / usr / bin
cd / usr / bin
Build a flexible connection
ln-s gcc-4.3 gcc
ln-s g+ + -4.3 g+ +
33./bin/bash: flex: command not found
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp] Error 127
a @ ubuntu: ~ / work / android / source_android $ sudo apt-get install flex
4.JNI. So file into the / system / lib and HAL moudule need into the / system / lib / hw and naming required to comply with the contract, eg: led.goldfish.so,
Now libhardware practice, there is "stub" taste. HAL stub is the concept of an agent (proxy), the stub still is * so file in the form of existence of HAL has * so file hide it. Stub HAL "" manipulation functions (operations), and the runtime is to HAL specific module (stub) Operations callback manipulation functions. Such an implementation framework of the indirect function call, HAL stub turn out to be a "contains" relationship, HAL contains many stub (agent). Runtime as long as the description of the "type", ie, module ID, you can obtain the operating function. The HAL implementation in hardware.c and hardware.h file. In real terms by loading * so file (dlopen) to call * SO where the symbol (symbol) to achieve. The so-called agent here, I feel Android uniform definition of the three structures, then a few "must" thus unifying the call interface the past libhardware_legacy practice traditional "module" approach, that is, *. So file as a shared library to use the direct function call at runtime (JNI part) to use the HAL Module. Through direct function call to operate the driver.
聯(lián)系客服