分享

Android Hal's role and programming examples

 WUCANADA 2015-04-29

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.
Of course, the application may not be required through the JNI way to load * so file (dlopen) practice calls * SO where the symbol (symbol) is also a way.
HAL reality Patrick Brady (Google) published in 2008, Google I / O speech " ", the proposed the Android HAL structure of Figure. We know from this chart of HAL's purpose is to Android framework and the Linux kernel complete "separated". Android not to over-reliance on the Linux kernel, a bit like "the kernel independent" means, so that the development of the Android framework development can not consider the driver.
Android source HAL main implementation is stored in the following directory:
Libhardware_legacy / - past implementation, to take the concept of link library module
2 libhardware / - The new version of the implementation, adjusted to the concept of HAL stub of
3. Ril / - Radio Interface Layer
Before the maturity of the HAL architecture implementation (planning), we first do a simple analysis of the status of HAL. Android HAL implementation is still scattered in different places, such as Camera, WiFi, and so on, so the directory does not contain all of the HAL program code.
HAL past

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多