android從應用層到HRL層調用流程

android從應用層到HRL層調用流程:


1.實現自己的LED燈HAL層代碼編寫

  

  (1)編寫Android.mk

   LOCAL_PATH := $(call my-dir)
   include $(CLEAR_VARS)
   LOCAL_MODULE_TAGS := optional
   LOCAL_PRELINK_MODULE := false
   LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw   //動態庫會放在system/lib/hw文件夾中。
   LOCAL_SHARED_LIBRARIES := liblog
   LOCAL_SRC_FILES := led_hal.c
   LOCAL_MODULE := led.default
   include $(BUILD_SHARED_LIBRARY)





   (2)編寫led_hal.h

     #ifndef ANDROID_LED_INTERFACE_H
     #define ANDROID_LED_INTERFACE_H
     #include <stdint.h>
     #include <sys/cdefs.h>
     #include <sys/types.h>
     #include <hardware/hardware.h>

__BEGIN_DECLS


struct led_device_t {
    struct hw_device_t common;

int (*led_open)(struct led_device_t* dev);
int (*led_ctrl)(struct led_device_t* dev, int which, int status);   //對led 燈進行操作接口。
};  

__END_DECLS

#endif  // ANDROID_LED_INTERFACE_H





(3)編寫led_hal.c 

#define LOG_TAG "LedHal"
#include <hardware/vibrator.h>
#include <hardware/hardware.h>
#include <cutils/log.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <hardware/led_hal.h>

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <utils/Log.h>

static int fd;

/** Close this device */
static int led_close(struct hw_device_t* device)
{
close(fd);
return 0;
}


/** open this device */

static int led_open(struct led_device_t* dev)
{
fd = open("/dev/leds", O_RDWR);
ALOGI("led_open : %d", fd);
if (fd >= 0)
return 0;
else
return -1;
}

//操作ioctl 驅動led 燈。
static int led_ctrl(struct led_device_t* dev, int which, int status)
{
int ret = ioctl(fd, status, which);
ALOGI("led_ctrl : %d, %d, %d", which, status, ret);
return ret;
}


//操作驅動所有的接口。

static struct led_device_t led_dev = {
.common = {
.tag   = HARDWARE_DEVICE_TAG,
.close = led_close,
},
.led_open  = led_open,
.led_ctrl  = led_ctrl,
};

//hal默認方法。

static int led_device_open(const struct hw_module_t* module, const char* id,
        struct hw_device_t** device)
{
*device = &led_dev;
return 0;
}


static struct hw_module_methods_t led_module_methods = {
    .open = led_device_open,
};


struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
    .id = "led",
    .methods = &led_module_methods,
};

//把新文件上傳到服務器, 所在目錄:
hardware/libhardware/include/hardware/led_hal.h
hardware/libhardware/modules/led/led_hal.c
hardware/libhardware/modules/led/Android.mk


(4)編譯動態庫

      $ mmm hardware/libhardware/modules/led



2.實現自己的HAL Led燈之JNI層代碼編寫:

(1)編寫JNI代碼 

      com_android_server_LedService.cpp



#define LOG_TAG "LedService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <hardware/led_hal.h>




namespace android
{
static led_device_t* led_device;  //led燈設備。


jint ledOpen(JNIEnv *env, jobject cls)
{
jint err;
    hw_module_t* module;
hw_device_t* device;


ALOGI("native ledOpen ...");


/* 1. hw_get_module */
    err = hw_get_module("led", (hw_module_t const**)&module);  //id ="led"與 led_hal.c 類的方法HAL_MODULE_INFO_SYM 屬性  .id = "led"一致
    if (err == 0) {
/* 2. get device : module->methods->open */
   err = module->methods->open(module, NULL, &device);
   if (err == 0) {
/* 3. call led_open */
       led_device = (led_device_t *)device;
return led_device->led_open(led_device);
   } else {
       return -1;
    }
    }


    return -1;
}


void ledClose(JNIEnv *env, jobject cls)
{
//ALOGI("native ledClose ...");
//close(fd);
}




//操作led燈
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
ALOGI("native ledCtrl %d, %d", which, status);
return led_device->led_ctrl(led_device, which, status);
}




static const JNINativeMethod methods[] = {
{"native_ledOpen", "()I", (void *)ledOpen},
{"native_ledClose", "()V", (void *)ledClose},
{"native_ledCtrl", "(II)I", (void *)ledCtrl},
};




int register_android_server_LedService(JNIEnv *env)
{
    return jniRegisterNativeMethods(env, "com/android/server/LedService",
            methods, NELEM(methods));
}


}


(2)修改frameworks/base/services/core/jni/onload.cpp



       1)在namespace android {}方法中添加

             int register_android_server_LedService(JNIEnv *env);



        2)extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved){}方法中添加

             register_android_server_LedService(env);


(3)修改 frameworks/base/services/core/jni/Android.mk :

        添加   $(LOCAL_REL_DIR)/com_android_server_LedService.cpp \

        


(4)把新文件上傳到服務器, 所在目錄:


     frameworks/base/services/core/jni/com_android_server_LedService.cpp
   

     

(5)編譯:
       $ mmm frameworks/base/services   //重新打包libandroid_servers.so動態庫。



3.實現自己的HAL Led燈之Service層代碼編寫


(1) 編寫AIDL     

     1) ILedService.aidl 


        package android.os;


        /** {@hide} */
       interface ILedService
    {
int ledCtrl(int which, int status);
     }


    2)把 ILedService.aidl 放入 frameworks/base/core/java/android/os
    3)修改 frameworks/base/Android.mk  添加一行
          core/java/android/os/IVibratorService.aidl \
       + core/java/android/os/ILedService.aidl \


  (2)編譯:mmm frameworks/base

                  它會生成: ./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ILedService.java

   

  

(3) 編寫LedService.java


   







    





     


   

    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章