安卓硬件服务程序框架
参考Vibrator来写:
1、.aidl程序
形如:
package android.os; interface ILedsService { int ledCtrl(int which, int status); }
这是应用程序需要用到的函数,应用程序不需要open
2、将ILedsService.aidl放到/work/android-5.0.2/frameworks/base/core/java/android/os目录下
修改base/Android.mk:
添加:core/java/android/os/ILedsService.aidl \
(执行mm命令之前一定要先编译安卓系统)
执行命令: mm 编译当前目录下的模块,当前目录要有Android.mk文件
mmm <dir> 编译指定目录下的模块,指定目录下要有Android.mk文件
得到ILedsService.java代码
3、应用程序
修改SystemServer.java,添加:
Slog.i(TAG, "Leds Service");
ServiceManager.addService("leds", new LedsService());
新建LedsService.java:
package com.android.server; import android.os.ILedsService; public class LedsService extends ILedsService.Stub { private static final String TAG = "LedsService"; public LedsService() { native_ledOpen(); } public int ledCtrl(int which, int status)throws android.os.RemoteException{ return naitve_ledCtrl(which, status); } public native int native_ledOpen(); public native void native_ledClose(); public native int naitve_ledCtrl(int which, int status); };
4、JNI接口(向上提供本地函数和加载HAL并调用HAL里的函数):
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/Log.h>
#include <hardware/Leds.h>
#include <stdlib.h>
#include <android/log.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <hardware/leds_hal.h>
{
jnit err;
struct leds_device_t* led_dev;
jint ledOpen(JNIEnv *env, jobject cls)
{
struct hw_module_t *module;
struct hw_device_t* dev;
err = hw_get_module("leds", (const struct hw_module_t **)&module);
if (err == 0)
err = module->methods->open(module,NULL,&dev);
if (err == 0) {
led_dev = (struct leds_device_t*)dev;
err = led_dev->led_open(led_dev);
}
return err;
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
return led_dev->led_ctrl(led_dev, status, which);
}
void ledClose(JNIEnv *env, jobject cls)
{
}
static JNINativeMethod gMethods[] ={
{"native_ledCtrl", "(II)I", (void *)ledCtrl},
{"native_ledOpen", "()I", (void *)ledOpen},
{"native_ledClose", "()V", (void *)ledClose},
};
int register_android_server_LedsService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/LedsService",
gMethods, NELEM(gMethods));
}
5、HAL(硬件抽象层:负责访问驱动程序执行硬件操作)
#include <hardware/hardware.h> #include <cutils/log.h> #include <android/log.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <math.h> #include <hardware/leds_hal.h>
//#define LOG_TAG "Led_Hal" static int fd; int led_close(struct leds_device_t* device) { close(fd); ALOGI("native ledClose\n"); return 0; } int led_open(struct leds_device_t* device) { fd = open("/dev/LED0", O_RDWR); if (fd < 0) return -1; ALOGI("native ledOpen\n"); return 0; } int led_ctrl(struct leds_device_t* device, int which, int status) { int ret = ioctl(fd, status, which); if (ret < 0) return -1; ALOGI("native ledCtrl: %d %d\n", which, status); return 0; } struct leds_device_t led_dev = { .common = { .close = led_close, }, .led_open = led_open, .led_ctrl = led_ctrl, }; int leds_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 = leds_device_open, }; struct hw_module_t HAL_MODULE_INFO_SYM = { .id = "leds", .methods = &led_module_methods, };
#ifndef _LEDS_HAL_H #define _LEDS_HAL_H
#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <hardware/hardware.h>
__BEDIN_DECLS struct leds_device_t { struct hw_device_t common; int (*led_open)(struct leds_device_t *dev); int (*led_ctrl)(struct leds_device_t *dev, int which, int status); }; __END_DECLS #endif
6、修改Onload.cpp:
添加: int register_android_server_LedsService(JNIEnv *env); 以及
register_android_server_LedsService(env);
编译android-5.0.2(mmm frameworks/base/services ./gen-img.sh),得到system.img映像文件
7、APP
以上修改的都是系统,APP在Android Studio 里面编写,需要import Android.os.ILedsService
private ILedsService iLedsService;
iLedsService = ILedsService.stab.asInterface(ServiceManager.getService("leds"));
调用iLedsService.ledCrtl(which,status);
但Android Studio并不知道有ILedsService这个接口,所以需要包含out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
target Java: framework (out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes)
在build.gradle下添加:
dexOptions {
javaMaxHeapSize"4g"
}
defaultConfig {
applicationId "com.example.zhu.zhu_first"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
+ multiDexEnabled true
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.1.1'
compile project(':classes')
+ compile 'com.android.support:multidex:1.0.0'
}
在AndroidManifest.xml里添加:android:name="android.support.multidex.MultiDexApplication"
dex文件是Android平台上可执行文件的类型,Android Studio 会对包含的jar文件转换成dex文件,而当DEX文件里面的方法超过
65535时(DEX文件里的方法数目是用short类型索引的,short类型最多65535),就得用multidex了。
对于Android DEX文件进行优化,需要注意的一点是DEX文件的结构是紧凑的,
但是我们还是要想方设法的进行提高程序的运行速度,我们就仍然需要对DEX文件进行进一步优化
调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的每一个域 验证DEX文件中的所有类 对一些特定的类进行优化,对方法里的操作码进行优化 。
优化后的文件大小会有所增加,应该是原Android DEX文件的1-4倍。 优化发生的时机有两个:对于预置应用,可以在系统编译后,生成优化文件,以ODEX结尾
这样做可以加快软件的启动速度,预先提取,减少对RAM的占用,因为没有odex的话,系统要从apk包中提取dex再运行
8、底层驱动
#include <linux/kernel.h> #include <linux/module.h> #include <linux/device.h> #include <linux/miscdevice.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/delay.h> #include <linux/gpio.h> #include <mach/gpio.h> #include <plat/gpio-cfg.h> static int major; static struct class *led_class; static int led_gpios[] = { EXYNOS4212_GPM4(0), EXYNOS4212_GPM4(1), EXYNOS4212_GPM4(2), EXYNOS4212_GPM4(3), }; static int PIN_NUM = sizeof(led_gpios)/sizeof(led_gpios[0]); static int leds_open(struct inode *inode, struct file *file) { int i; for (i = 0; i < 4; i++) { s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT); } return 0; } static long leds_ioctl (struct file *file, unsigned int cmd, unsigned long arg) { if (cmd != 0 && cmd !=1) return EINVAL; if (arg > 3) return EINVAL; gpio_set_value(led_gpios[arg], !cmd); return 0; } struct file_operations leds_ops = { .owner = THIS_MODULE, .open = leds_open, .unlocked_ioctl = leds_ioctl, }; int leds_init(void) { major = register_chrdev(0, "led", &leds_ops); led_class = class_create(THIS_MODULE, "led"); device_create(led_class, NULL, MKDEV(major,0), 0, "LED0"); return 0; } void leds_exit(void) { device_destroy(led_class, MKDEV(major,0)); class_destroy(led_class); } module_init(leds_init); module_exit(leds_exit); MODULE_LICENSE("GPL");
放入linux内核drivers/char下,修改Makefile
编译出zImage: make zImage
9、程序执行过程:
SystemServer.java里的main方法-->run方法-->
// Initialize native services.
System.loadLibrary("android_servers"); -->加载C库,调用onload.cpp