上一篇文章已经写了led驱动,这篇文章我们再封装HAL层
1.在源码hardware/libhardware/include/hardware/目录下增加test_led_hal.h
内容如下
#ifndef TEST_LED_HAL_H #define TEST_LED_HAL_H #include <hardware/hardware.h> #include <fcntl.h> #include <errno.h> #include <cutils/log.h> #include <cutils/atomic.h> #define LED_HARDWARE_MODULE_ID "test_led" //HAL 规定不能直接使用hw_module_t结构,因此需要做这么一个继承。 //见hardware.h中的hw_module_t定义的说明,xxx_module_t的第一个成员必须是hw_module_t类型,其次才是模块的一此相关信息,当然也可以不定义, //这里就没有定义模块相关信息 struct led_module_t { struct hw_module_t common; /* support API for LEDServices constructor */ }; //自定义的一个针对Led控制的结构,包含hw_device_t和支持的API操作 //见hardware.h中的hw_device_t的说明,要求自定义xxx_device_t的第一个成员必须是hw_device_t类型,其次才是其它的一些接口信息. struct led_control_device_t { struct hw_device_t common; /* supporting control APIs go here */ int (*led_set_on)(struct led_control_device_t *dev); }; #endif
2.在源码hardware\libhardware\modules目录下建一个目录test_led,再在该目录下面创建两个文件test_led_hal.c、Android.mk 内容分别如下:
#define LOG_TAG "LedStub" #include <hardware/hardware.h> #include <fcntl.h> #include <errno.h> #include <cutils/log.h> #include <cutils/atomic.h> #include <sys/ioctl.h> #include <hardware/test_led_hal.h> #define LED_ON 0x4800 //硬件led的设备描述符 。你也可以用led_control_device_t结构中定义的fd int fd; static 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); } close(fd); return 0; } static int led_set_on(struct led_control_device_t *dev) { //FIXME: do system call to control gpio led LOGI("led_set_on"); ioctl(fd, LED_ON, NULL); 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 = (struct led_control_device_t*) malloc( sizeof(struct led_control_device_t)); //动态分配空间 if (!dev) { LOGE("TestLed Stub: failed to alloc space"); return -EFAULT; } memset(dev, 0, sizeof(struct led_control_device_t)); //对dev->common的内容赋值, dev->common.tag = HARDWARE_DEVICE_TAG; //必须为这个值 dev->common.version = 0; dev->common.module = (hw_module_t*) module; dev->common.close = led_device_close; // 初始化控制 API dev->led_set_on = led_set_on; //实例化支持的操作 //打开硬件设备 if ((fd = open("/dev/testLed2", O_RDWR)) == -1) { LOGI("open error"); free(dev); return -EFAULT; } else { LOGI("open ok\n"); } //将实例化后的led_control_device_t地址返回给jni层 ,这样jni层就可以直接调用API方法了 *device = (struct hw_device_t *) (&(dev->common)); return 0; } static struct hw_module_methods_t led_module_methods = { open: led_device_open }; //定义这个对象等于向系统注册了一个ID为LED_HARDWARE_MODULE_ID的stub。注意这里HAL_MODULE_INFO_SYM的名称不能改。 const struct led_module_t HAL_MODULE_INFO_SYM = { common: { tag: HARDWARE_MODULE_TAG, //必须为 HARDWARE_MODULE_TAG version_major: 1, version_minor: 0, id: LED_HARDWARE_MODULE_ID, name: "led HAL module", author: "kk", methods: &led_module_methods,//实现了一个open的方法供jni层调用, 从而实例化led_control_device_t }, /* supporting APIs go here */ };
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := test_led.default LOCAL_PRELINK_MODULE := false LOCAL_SHARED_LIBRARIES := liblog libcutils lm -llog # set shared libary out path #TARGET_OUT_SHARED_LIBRARIES:= $(TARGET_OUT)/lib/hw LOCAL_MODULE_PATH :=$(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_SRC_FILES := test_led_hal.c include $(BUILD_SHARED_LIBRARY)
3.重新编译,生成HAL层接口。APP可以直接通过jni代码调用HAL,也可以再封装一层SystemServer,SystemServer调用HAL,然后APP通过AIDL调用SystemServer
4.以下为jni调用的部分例子代码:com_android_server_test_led.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 "test_led_hal.h" namespace android { static led_control_device_t *sLedDevice = 0; static led_module_t* sLedModule = 0; static jint led_setOn(JNIEnv* env, jobject thiz) { ALOGE("%s E", __func__); if (sLedDevice) { sLedDevice->led_set_on(sLedDevice); //调用hal层的注册的方法 } else { ALOGE("sLedDevice is null"); } return 0; } /** helper APIs */ static inline int led_control_open(const struct hw_module_t* module, struct led_control_device_t** device) { ALOGE("%s E ", __func__); return module->methods->open(module, LED_HARDWARE_MODULE_ID, (struct hw_device_t**) device); //这个过程非常重要,jni通过LED_HARDWARE_MODULE_ID找到对应的stub } //hw_get_module获得一个hw_module_t结构体 ,调用 module->methods->open(module, device_name, &device) 获得一个hw_device_t结构体,并且把hw_device_t结构体转换为设备自定义的结构体 static jint led_init(JNIEnv *env, jclass clazz) { led_module_t const * module; ALOGE("%s E ", __func__); if (hw_get_module(LED_HARDWARE_MODULE_ID, (const hw_module_t**) &module) == 0) { //根据LED_HARDWARE_MODULE_ID找到hw_module_t,参考hal层的实现 ALOGE("get Module OK"); sLedModule = (led_module_t *) module; if (led_control_open(&module->common, &sLedDevice) != 0) { //通过hw_module_t找到led_control_device_t ALOGE("led_init error"); return -1; } } ALOGE("led_init success"); return 0; } //Framework层调用的映射,第一个参数为jni暴露给java的方法,第三个参数为jni层的方法,即为一个函数指针 //第二个参数:“()” 中的字符表示参数,后面的则代表返回值。例如”()V” 就表示void * Fun(); // “(II)V” 表示 void Fun(int a, int b); // “(II)I” 表示 int addInt(int a, int b); // "()Ljava/lang/String;" 表示String getStr(); static const JNINativeMethod gMethods[] = { { "led_init", "()I", (void*) led_init }, { "set_on", "()I", (void*) led_setOn }, }; int register_android_server_TestLedService(JNIEnv* env) { //注意:必须和你Framework层的service类名相同 // static const char* const kClassName = "com/android/server/test_led"; //或者jni暴露给java层的类所在路径相同,这里因为不做成SystemServer,所以名字可以修改为com/test/hardware/TestLed,只需要在app保护一个类com.test.hardware.TestLed.java即可, static const char* const kClassName = "com/test/hardware/TestLed"; jclass clazz; /* look up the class */ clazz = env->FindClass(kClassName); if (clazz == NULL) { ALOGE("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) { ALOGE("Failed registering methods for %s\n", kClassName); return -1; } /* fill out the rest of the ID cache */ return 0; } /* * * java调用 System.loadLibrary触发该函数。因为在这里我们直接集成到libandroid_servers.so,所以这个函数不使用 */ //jint JNI_OnLoad(JavaVM* vm, void* reserved) { // // JNIEnv* env = NULL; // ALOGE("JNI_OnLoad"); // // //从JavaVM获取JNIEnv,一般使用1.4的版本 // if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { // ALOGE("ERROR: GetEnv failed\n"); // return -1; // } // // if (env == NULL) { // // ALOGE("ERROR: env is NULL\n"); // return -1; // } // // if (register_android_server_TestLedServi(env) != 0) { //注册你的JNINativeMethod // ALOGE("ERROR: PlatformLibrary native registration failed\n"); // return -1; // } // //这里很重要,必须返回版本,否则加载会失败 // return JNI_VERSION_1_4; //} }
相关推荐
而`LedTest.rar`可能是一个LED测试应用的源码,开发者可以通过这个例子学习如何在Android平台上控制硬件设备,比如LED灯,通过调用HAL层的接口来实现。 在实际开发中,开发者需要了解这四个层次的工作原理,并且...
AndroidQ 打通应用层到HAL层—(HAL模块实现)这篇文章中我们已经实现了自己的HAL,本篇我们实现一个HIDL服务,通过这个服务来调用HAL模块的函数 什么是HIDL HIDL 全称为HAL interface definition language(发音为...
- **Android电话系统的层次结构**:电话系统包括应用程序层、核心库层和HAL层。 #### 10.2 电话系统组成部分 - **Android电话系统的本地和JAVA程序运行流程**:涉及到电话呼叫、短信处理等功能。 #### 10.3 电话...
在Android系统中,硬件抽象层(Hardware Abstraction Layer,简称HAL)是操作系统与硬件设备之间的桥梁,它使得上层软件可以以统一的方式访问各种不同硬件的特性,而无需关心具体的硬件实现细节。"fingerprint HAL...
前面两篇文章实现了自定义HAL和HIDL服务,本篇接着往上层实现,这篇文章要写的是JNI服务和framework层AIDL服务实现,由AIDL服务调用JNI层的服务的函数,为了提供给上层APP使用 同样我们参照系统其他服务的方式来写,...
Android的硬件抽象层(HAL,Hardware Abstraction Layer)负责封装底层硬件接口,使得上层软件如系统服务或应用程序能够透明地使用硬件资源。 在Android的LED驱动开发过程中,首先需要创建一个HAL模块。HAL模块通常...
Linux内核作为Android的基础,提供了硬件抽象层(HAL,Hardware Abstraction Layer)和驱动程序。HAL使得上层软件对硬件的操作标准化,而驱动程序则是操作系统与硬件设备之间的接口。例如,AudioFlinger服务通过HAL...
例如,通过阅读和分析系统服务、框架层或HAL(硬件抽象层)的代码,开发者可以学习如何与硬件交互、如何管理应用程序生命周期,甚至创建自定义ROM。源码的获取通常需要通过Git从AOSP(Android Open Source Project)...
"ANDROID HAL JNI 演练"是这个项目的一个重要部分,它聚焦于Android硬件抽象层(Hardware Abstraction Layer, HAL)以及JNI(Java Native Interface)的使用。下面我们将详细探讨这两个关键概念。 1. **Android硬件...
《Android深度探索 卷1:HAL与驱动开发》是一本专为Android系统开发者和爱好者编写的书籍,旨在深入解析Android系统的硬件抽象层(HAL)以及驱动程序开发的关键技术和实践。这本书全面涵盖了Android系统中硬件接口的...
Android项目之AidlDemo(简单的aidl的例子)。AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写。需要的小伙伴自请下载。
5. **system**:`system`通常涉及Android系统的底层服务和核心组件,如电源管理、网络服务、硬件抽象层(HAL)等。研究这部分源码,可以帮助开发者了解系统级服务的实现,进行系统级别的优化。 6. **security**:安全...
第14章Android HAL层的设计 14.1 Android HAL概述 14.2为Android开发虚拟驱动virtualio 14.3 Android集成C程序访问virtualio 14.4 Android通过HAL访问virtualio 14.4.1 virtualio HAL模块实现 14.4.2实现访问virtual...
1. Android硬件抽象层(HAL)的概念和作用: Android硬件抽象层是Linux内核驱动程序的封装层,它在用户空间提供接口给上层应用,同时隐藏了底层实现的细节。HAL的存在将硬件支持分为用户空间层和内核空间层,用户...
在C/C++代码中,你可以使用Android的HAL(Hardware Abstraction Layer)接口来访问设备的背光控制器,并通过JNI调用来改变亮度。在Java层,你可以创建一个方法接收用户输入,然后调用JNI方法来更新背光设置。 总的...
《Android R HIDL服务实现应用层到HAL层通信详解》 在Android系统中,硬件抽象层(Hardware Interface Definition Language,简称HIDL)是连接应用程序框架层与硬件服务层的关键桥梁。它提供了一种标准化的方式,...
在Android系统中,相机功能是通过Camera HAL(硬件抽象层)来实现的,它负责与实际的硬件设备交互,提供给上层应用一个统一的接口。Android Camera HAL的设计允许开发者针对不同的硬件平台定制相机功能,以满足不同...