zoukankan      html  css  js  c++  java
  • 安卓硬件服务程序框架

    参考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里的函数):

    #define LOG_TAG "LedsService"
    #include "jni.h"
    #include "JNIHelp.h"
    #include "android_runtime/AndroidRuntime.h"
    #include <utils/misc.h>
    #include <utils/Log.h>
    #include <hardware/Leds.h>
    #include <stdio.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>
    namespace android
    {
     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 "); return 0; } int led_open(struct leds_device_t* device) { fd = open("/dev/LED0", O_RDWR); if (fd < 0) return -1; ALOGI("native ledOpen "); 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 ", 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

  • 相关阅读:
    【leetcode】974. Subarray Sums Divisible by K
    【leetcode】976. Largest Perimeter Triangle
    【leetcode】973. K Closest Points to Origin
    listen 70
    科学60秒 (一) :上
    listen 69
    listen 68 Theoretical Physicist Stephen Hawking Dies at 76
    中译英33
    listen 67
    中译英32
  • 原文地址:https://www.cnblogs.com/zhu-g5may/p/10480119.html
Copyright © 2011-2022 走看看