Android系统添加新硬件

本文基于android系统源码情景分析-罗升阳

kernel driver

kernel/driver

    ----freg

        ----freg.h

        ----freg.c

        ----Konfig 

        ----Makefile 

    ----Kconfig

    ----Makefile

#kernel/driver/freg/Konfig
#使得make menuconfig可以选择是否编译进内核或者编译成模块
congfig FREG 
			tristate "Fake Register Driver"
			default n
			help
			This is the freg driver for android system.
#kernel/driver/freg/Makefile
obj-$(CONFIG_FREG) += freg.o
#kernel/driver/Konfig
menu "Device Drivers"
source "drivers/freg/Konfig"
......
endmenu
#kernel/driver/Makefile
obj-$(CONFIG_FREG) += freg/

HAL

Android系统中HAL模块由系统统一加载。当调用者需要使用这些模块时指定id就行。

int hw_get_module(const char *id, const struct hw_module_t **module);

编译好的模块位于out/target/product/generic/system/lib/hw.经过打包后位于设备的/system/lib/hw或vendor/lib/hw下。

Android/hardware/libhardware

----include

----hardware/libhardware
----freg.h
----modules
----freg
----freg.cpp
----Android.mk

Frameworks

frameworks/base/core/java/android/os/IFregServer.aidl

frameworks/base/services/java/com/android/server/FregServer.java

frameworks/base/services/jni/com_android_service_FregServer.cpp

#frameworks/base/services/java/com/android/server/SystemService.java


AIDL

    Android APP直接通过Service(service extend AIDL.Stub)调用.so格式的JNI。

    标准方法:APP经过Manager(在framework层通过ServiceManager得到具体的Service)调用Service。

    Android标准方式APP和manager为一体,manager和service之间也利用AIDL进行通信。

    Android系统的硬件访问服务运行在系统进程System中,而需要使用硬件访问服务的APP运行在另外进程。定义硬件访问服务接口,使得APP可以调用。mmm./frameworks/base/ 编译后得到framework.jar包含IFregServer接口。IFregServer.aild被转换为java程序。IFregServer继承android.os.IInterface接口, IFregServer内部定义了一个Binder本地对象类Stub,它实现了IFregServer接口(setval, getval)。IFregServer.Stub类内部定义了一个Binder代理对象类Proxy,它也实现了IFregServer接口。

    每个服务都对应一个Binder本地对象,它通过Stub来等待Client进程发送进程间通信请求。Client进程首先获得Server的一个Binder代理对象连接口Proxy,通过Proxy发送通信请求。

frameworks/base/
----core/java/android/os/
----IFregServer.aidl
----Android.mk #在LOACL_SRC_FILES中加入IFregServer.aidl

FregServer.java

APP通过AIDL调用FregServer.jar(应用层调用时只需要ServiceManager.getService("freg"), 然后再调用其中的setVal()和getVal() ),FregServer.java再调用jni

frameworks/base/services/java/com/android/server/FregServer.java

#frameworks/base/services/java/com/android/server/FregServer.java
public class FregService extends IFregService.Stub{
	private int mPtr = 0;//表示是否初始化成功
	FregService(){
		mPtr = init_native;
		......
	}
	
	public void setVal(int val){
		setVal_native(mPtr, val);
	}
	
	public int getVal(int val){
		return getVal_native(mPtr);
	}
	
	private static native int init_native();
	private static native void setVal_native(int ptr, int val);
	private static native int getVal_native(int ptr);
}

JNI

jni调用HAL。mmm ./frameworks/base/services/jni/重写编译后得到libandroid_servers.so就包含init_native, setVal_native, getVal_native。

frameworks/base/services/jni/

    ----com_android_service_FregServer.cpp

    ----onload.cpp

    ----Android.mk

#frameworks/base/services/jni/com_android_service_FregServer.cpp
namespace android{
	static void freg_setVal(JNIEnv* env, jobject clazz, jint ptr, int vale){
		......
		device->set_val(device, val);
	}
	static jint freg_getVal(JNIEnv* env, jobject clazz, jint ptr){
		......
	}
	static inline int freg_device_open(const hw_module_t* module, struct freg_device_t** device){
		return module->methods->open(module, FREG_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);
	}
	static jint freg_init(JNIEnv* env, jobject clazz){
		hw_get_module(FREG_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module){
			......
			freg_device_open(&(module->commom), &device);
		}
	}
	 
	static const JNINativeMethod method_table[] = {
		{"init_native", "()I", (void*)freg_init},
		{"setVal_native", "(II)V", (void*)freg_setVal},
		{"getVal_native", "(I)I", (void*)freg_getVal}
	};
	
	int register_android_server_FregServer(JNIEnv *env){
		return jniRegisterNativeMethods(env, "com/android/server/FregService", method_table, NELEM(method_table));
	}
}
#frameworks/base/services/jni/onload.cpp
namespace android{
	......
	int register_android_server_FregServer(JNIEnv *env);
};

using namespace android;
extern "C" jint JIN_OnLoad(JavaVM* vm, void* reserved){
	......
	register_android_server_FregServer(env);
	return JNI_VERSION_1_4;
} 


启动硬件访问服务

#frameworks/base/services/java/com/android/server/SystemService.java

#frameworks/base/services/java/com/android/server/SystemService.java
class ServerThread extends Thread{
	public void run(){
		......	
		ServiceManager.addService("freg", new FregService());
	}

猜你喜欢

转载自blog.csdn.net/qq_23084801/article/details/80557318
今日推荐