Android系统中硬件访问服务框架(JNI HAL)及实例
来源:互联网 发布:windows 远程桌面 软件 编辑:程序博客网 时间:2024/06/01 09:52
在学习了硬件访问服务框架之后,以led为例,总结了Android app通过服务访问硬件的框架
实现:
1. JNI和HAL
//用来注册JNI本地方法(jniRegisterNativeMethods)
实现com_android_server_LedService.cpp
//实现HAL本地方法调用c函数:open、close、ioctl 具体实现参考文章最后
hal_led.c
hal_led.h
2. 修改onload.cpp
register_android_server_LedService(env); 调用各个硬件JNI中的注册本地方法的接口函数 进行本地方法的注册
最终编译生成libandroid_servers.so
3. 修改SystemServer.java 创建一个LedService对象并add这个service
System.loadLibrary(“android_servers”); //加载库,执行jniOnLoad方法
LedService led = new LedService();
ServiceManager.addService(“led”, led);
4. 创建LedService.java 去调用JNI提供的native方法
这个LedService类要继承ILedService接口,实现接口中的方法。至此,一个LedService服务就创建成功了,但是最终要通过步骤3将这个服务添加到系统中通过service_manager这个进程来进行管理所有的服务。
5. 创建ILedService.java接口,供app使用
这个接口通过编写一个对应的ILedService.aidl文件然后mmm编译在out目录下生成对应的ILedService.java接口, 参考IVibratorService.aidl文件。
编写HAL代码:
JNI 向上提供本地函数,向下加载HAL文件并调用 HAL的函数
HAL 负责访问驱动程序执行硬件操作
JNI加载HAL的实质是JNI如何使用dlopen来加载HAL的动态库
1. JNI如何使用HAL
a. 使用hw_get_module获得hw_module_t结构体
b. 调用module->methods->open(module, name, &device); // name – 设备的名字,一个so可能包含多个device
调用moudle的open函数获取一个hw_device_t结构体(设备结构体)。
(light_device_t*)device; //并且将设备结构体转换为自定义的结构体
2. HAL怎么写
a. 要实现一个名字为HMI的hw_module_t结构体
b. 要实现一个open函数,根据传入的name返回一个设备自定义结构体,这个结构体的第一成员是hw_device_t结构体。
对修改或者新加的文件处理:
led_hal.c
hardware/libhardware/modules/led
mk文件可以cp ../vibratory/Android.mk进行修改
led_hal.h
hardware/libhardware/include/hardware
com_android_service.led.cpp
frameworks/base/services/core/jni
ILedLService.aidl
frameworks/base/core/java/android/os/ILedService.aidl
frameworks/base$ vi Android.mk进行修改
生成.java需在当前目录下执行mmm命令
SystemServer.java
frameworks/base/services/java/com/android/server
LedService.java
frameworks/base/services/core/java/com/android/server
修改frameworks/base/services/core/Android.mk
onload.cpp
frameworks/base/services/core/jni
修改frameworks/base/services/core/jni/Android.mk
mmm frameworks/base/services
mmm hardware/libhardware/modules/led
make snod
./gen-img.sh
从新烧写system.img
最后app如何使用:
1. as工程要包含什么?
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
2. 怎么包含
a. Creating a module library and adding it to module dependencies
file->project structure->+ ->import .jar ->classer.jar
file->project structure->app->dependencies ->+ module depends -> classer
b. 编译报错:java.lang.OutOfMemoryError: GC overhead limit exceeded
修改build.gradle,添加
dexOptions { javaMaxHeapSize "4g"}
c. 编译报错: Too many field references Building Apps with Over 65K Methods
修改build.gradle
android { defaultConfig { multiDexEnabled truedependencies { compile 'com.android.support:multidex:1.0.1'
修改AndroidManifest
<application android:name="android.support.multidex.MultiDexApplication"
关于他们之间的关系:
最后附上相关代码:
LedService.java
/************************************************************************* > File Name: LedService.java > Author: hanp > Mail: 18336073186@163.com > Created Time: 2017年07月26日 星期三 16时23分18秒 ************************************************************************/package com.android.server;import android.os.ILedService;import android.util.Slog;/* 调用本地native方法,操作硬件 */public class LedService extends ILedService.Stub{ private static final String TAG = "LedService"; public LedService() { Slog.i(TAG, "public LedService()"); native_ledOpen(); } public void ledCtrl(int which, int status) throws android.os.RemoteException { Slog.i(TAG, "ledCtrl(int which = "+which+", int status = "+status+")"); native_ledCtrl(which, status); } public static native void native_ledOpen(); public static native void native_ledCtrl(int which, int status); public static native void native_ledClose();}
SystemService.java
/* 向servicemanger添加一个service */Slog.i(TAG, "Led Service");LedService led = new LedService();ServiceManager.addService("led", led);
com_android_service_LedService
/************************************************************************* > File Name: com_android_server_LedService.cpp > Author: hanp > Mail: 18336073183@163.com > Created Time: 2017年07月26日 星期三 16时53分51秒 ************************************************************************/#include<iostream>#include "jni.h"#include "JNIHelp.h"#include <utils/Log.h>#include <stdio.h>#include "android_runtime/AndroidRuntime.h"#include <utils/misc.h>#include <hardware/led_hal.h>#include <hardware/hardware.h>#define LOG_TAG "LedService"namespace android{static led_device_t * led_dev;JNIEXPORT void JNICALL ledOpen(JNIEnv * env, jclass cls){ jint err; hw_device_t * device; hw_module_t * module; ALOGI("JNI native method led_open ..."); /* 1. get modules hw_get_module */ /* 2. call module->methods->open method get a hw_device_t structure */ /* 3. call led_open */ err = hw_get_module("led", (hw_module_t const**)&module); if (err == 0) { err = module->methods->open(module, NULL, &device); if (err == 0) { led_dev = (led_device_t*)device; led_dev->led_open(led_dev); } else { ALOGI("JNI native get module err ..."); } } return;}JNIEXPORT void JNICALL ledClose(JNIEnv * env, jclass cls){ ALOGI("JNI native method led_close ...");}/* status 0 -- off 1 -- on */JNIEXPORT void JNICALL ledCtrl(JNIEnv * env, jclass cls, jint which, jint status){ ALOGI("JNI native method led_ctrl ..."); led_dev->led_ctrl(led_dev, which, status); return;}const JNINativeMethod methods[] = { {"native_ledOpen", "()V", (void *)ledOpen}, {"native_ledClose", "()V", (void *)ledClose}, {"native_ledCtrl", "(II)V", (void *)ledCtrl},};int register_android_server_LedService(JNIEnv *env){ ALOGI("JNI native method register_android_server_LedService ..."); /* 将本地method注册到LEDService这个服务中*/ return jniRegisterNativeMethods(env, "com/android/server/LedService", methods, NELEM(methods));}};
hal_led.c
/************************************************************************* > File Name: led_hal.c > Author: hanp > Mail: 18336073183@163.com > Created Time: 2017年07月31日 星期一 15时00分30秒 ************************************************************************/#include<stdio.h>#include <hardware/hardware.h>#include <hardware/led_hal.h>#include <cutils/log.h>#include <utils/Log.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <errno.h>#include <math.h>#include "led.h"#define LOG_TAG "LedHal"/* 1. 定义一个名字为HMI的hw_device_t类型的结构体 *//* 2. 实现一个open函数,并根据传入的name返回一个自定义的设备结构体 (led_device_t) *//* 3. 根据传入name的定义一个自定义的设备结构体 -- led_device_t, 这个结构体的第一个成员是hw_device_t结构体 */static int fd;static void led_open(led_device_t * dev){ fd = open("/dev/led", O_RDWR); ALOGI("hal method led_open ..."); if (fd < 0) { ALOGI("hal method led_open open /dev/led err ..."); return ; }}static int led_close(struct hw_device_t * dev){ ALOGI("hal method led_close ..."); close(fd); return 0;}static void led_ctrl(led_device_t * dev, int which, int status){ ALOGI("hal method led_ctrl ..."); switch (status) { case 1: ioctl(fd, LED_ON, which); break; case 0: ioctl(fd, LED_OFF, which); break; default: ALOGI("hal method led_ctrl invaled argument ..."); break; }}static led_device_t led_device = { .common = { .tag = HARDWARE_DEVICE_TAG, .close = led_close, }, .led_open = led_open, .led_ctrl = led_ctrl,};static int led_device_open(const hw_module_t* module, const char* id, hw_device_t** device){ *device = &led_device; //通过参数,传回led_device_t结构体 return 0;}static struct hw_module_methods_t led_module_methods = { .open = led_device_open,};struct hw_module_t HAL_MODULE_INFO_SYM = { //#define HAL_MODULE_INFO_SYM HMI .tag = HARDWARE_MODULE_TAG, .id = "led", .methods = &led_module_methods,};
- Android系统中硬件访问服务框架(JNI HAL)及实例
- tiny210 hal 6 Android系统中编写APP通过应用程序框架层访问硬件服务。
- tiny210 hal 4 Android系统中编写JNI方法在应用程序框架层提供Java接口访问硬件
- Android硬件访问服务-HAL
- 硬件访问服务4之Android硬件访问服务框架及系统函数全详细实现
- (三)为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- (四)在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 每日一题(1) —— 数组计算
- SQL
- hdu2103 01背包
- JavaScript特点、优缺点及常用框架
- 测试流程规范
- Android系统中硬件访问服务框架(JNI HAL)及实例
- c#程序开发中几个注意事项
- hadoop入门(三)之 javaAPI操作Hdfs,进行文件操作
- AngularJs 中将表格导出生成Excel表
- 安装zabbix_orabbix监控的步骤
- ffmpeg+opencv
- 通过overScrollBy实现下拉视差特效(阻尼效果)
- CodeForces6E st查询
- css : div