`

android HAL层例子

 
阅读更多

上一篇文章已经写了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;
//}
}

 

 

分享到:
评论

相关推荐

    s5p4418 Android 4.4.2 驱动层 HAL层 服务层 应用层 开发流程记录(三 APP应用)源码

    而`LedTest.rar`可能是一个LED测试应用的源码,开发者可以通过这个例子学习如何在Android平台上控制硬件设备,比如LED灯,通过调用HAL层的接口来实现。 在实际开发中,开发者需要了解这四个层次的工作原理,并且...

    AndroidQ 打通应用层到HAL层—(HIDL服务实现)

    AndroidQ 打通应用层到HAL层—(HAL模块实现)这篇文章中我们已经实现了自己的HAL,本篇我们实现一个HIDL服务,通过这个服务来调用HAL模块的函数 什么是HIDL HIDL 全称为HAL interface definition language(发音为...

    android-framework-hal

    - **Android电话系统的层次结构**:电话系统包括应用程序层、核心库层和HAL层。 #### 10.2 电话系统组成部分 - **Android电话系统的本地和JAVA程序运行流程**:涉及到电话呼叫、短信处理等功能。 #### 10.3 电话...

    fingerprint hal

    在Android系统中,硬件抽象层(Hardware Abstraction Layer,简称HAL)是操作系统与硬件设备之间的桥梁,它使得上层软件可以以统一的方式访问各种不同硬件的特性,而无需关心具体的硬件实现细节。"fingerprint HAL...

    AndroidQ 打通应用层到HAL层—(JNI服务和AIDL服务实现)

    前面两篇文章实现了自定义HAL和HIDL服务,本篇接着往上层实现,这篇文章要写的是JNI服务和framework层AIDL服务实现,由AIDL服务调用JNI层的服务的函数,为了提供给上层APP使用 同样我们参照系统其他服务的方式来写,...

    android led 测试例子

    Android的硬件抽象层(HAL,Hardware Abstraction Layer)负责封装底层硬件接口,使得上层软件如系统服务或应用程序能够透明地使用硬件资源。 在Android的LED驱动开发过程中,首先需要创建一个HAL模块。HAL模块通常...

    Android各个层次之间的相互关系

    Linux内核作为Android的基础,提供了硬件抽象层(HAL,Hardware Abstraction Layer)和驱动程序。HAL使得上层软件对硬件的操作标准化,而驱动程序则是操作系统与硬件设备之间的接口。例如,AudioFlinger服务通过HAL...

    android sdk源码例子平台文档

    例如,通过阅读和分析系统服务、框架层或HAL(硬件抽象层)的代码,开发者可以学习如何与硬件交互、如何管理应用程序生命周期,甚至创建自定义ROM。源码的获取通常需要通过Git从AOSP(Android Open Source Project)...

    mokroid--android经典例子演练

    "ANDROID HAL JNI 演练"是这个项目的一个重要部分,它聚焦于Android硬件抽象层(Hardware Abstraction Layer, HAL)以及JNI(Java Native Interface)的使用。下面我们将详细探讨这两个关键概念。 1. **Android硬件...

    Android深度探索 卷1 :HAL与驱动开发

    《Android深度探索 卷1:HAL与驱动开发》是一本专为Android系统开发者和爱好者编写的书籍,旨在深入解析Android系统的硬件抽象层(HAL)以及驱动程序开发的关键技术和实践。这本书全面涵盖了Android系统中硬件接口的...

    Android项目之AidlDemo(简单aidl的例子)

    Android项目之AidlDemo(简单的aidl的例子)。AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写。需要的小伙伴自请下载。

    android 7.1 源码附带例子——2

    5. **system**:`system`通常涉及Android系统的底层服务和核心组件,如电源管理、网络服务、硬件抽象层(HAL)等。研究这部分源码,可以帮助开发者了解系统级服务的实现,进行系统级别的优化。 6. **security**:安全...

    Android驱动开发权威指南

    第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...

    《Android驱动开发全过程》

    1. Android硬件抽象层(HAL)的概念和作用: Android硬件抽象层是Linux内核驱动程序的封装层,它在用户空间提供接口给上层应用,同时隐藏了底层实现的细节。HAL的存在将硬件支持分为用户空间层和内核空间层,用户...

    android的jni调用例子

    在C/C++代码中,你可以使用Android的HAL(Hardware Abstraction Layer)接口来访问设备的背光控制器,并通过JNI调用来改变亮度。在Java层,你可以创建一个方法接收用户输入,然后调用JNI方法来更新背光设置。 总的...

    hello_hidl.rar

    《Android R HIDL服务实现应用层到HAL层通信详解》 在Android系统中,硬件抽象层(Hardware Interface Definition Language,简称HIDL)是连接应用程序框架层与硬件服务层的关键桥梁。它提供了一种标准化的方式,...

    android camera

    在Android系统中,相机功能是通过Camera HAL(硬件抽象层)来实现的,它负责与实际的硬件设备交互,提供给上层应用一个统一的接口。Android Camera HAL的设计允许开发者针对不同的硬件平台定制相机功能,以满足不同...

Global site tag (gtag.js) - Google Analytics