无网不进  
软硬件开发

Android下,java应用程序通过JNI方法调用硬件抽象层模块,在Android 从硬件到应用:一步一步向上爬 3 -- 硬件抽象层访问硬件驱动

中我们已经编译好了硬件抽象层模块,下面就要开始为HAL层编写JNI方法,为上层提供服务。

cd到frameworks/base/services/jni目录中,新建一个com_android_server_GpioService.cpp文件:

 

[javascript] view plain copy
 
  1. #include "jni.h"    
  2. #include "JNIHelp.h"    
  3. #include "android_runtime/AndroidRuntime.h"    
  4. #include <utils/misc.h>    
  5. #include <utils/Log.h>    
  6. #include <hardware/hardware.h>    
  7. #include <hardware/gpio.h>    
  8. #include <stdio.h>    
  9. namespace android    
  10. {    
  11.     struct gpio_device_t* gpio_device = NULL;    
  12.   
  13.     static void gpio_setVal(JNIEnv* env, jobject clazz, jint value)   
  14.     {    
  15.         int val = value;      
  16.         gpio_device->set_val(gpio_device, val);    
  17.     }    
  18.      
  19.     static jint gpio_getVal(JNIEnv* env, jobject clazz)   
  20.     {    
  21.         return 0;    
  22.     }    
  23.           
  24.     static inline int gpio_device_open(const hw_module_t* module, struct gpio_device_t** device)   
  25.     {    
  26.         return module->methods->open(module, GPIO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);    
  27.     }    
  28.        
  29.     static jboolean gpio_init(JNIEnv* env, jclass clazz)   
  30.     {    
  31.         gpio_module_t* module;    
  32.         if(hw_get_module(GPIO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0)   
  33.         {    
  34.             if(gpio_device_open(&(module->common), &gpio_device) == 0)  
  35.             {    
  36.                 return 0;    
  37.             }      
  38.             return -1;    
  39.             }    
  40.         return -1;          
  41.     }    
  42.         
  43.     static const JNINativeMethod method_table[] =   
  44.     {    
  45.         {"init_native", "()Z", (void*)gpio_init},    
  46.         {"setVal_native", "(I)V", (void*)gpio_setVal},    
  47.         {"getVal_native", "()I", (void*)gpio_getVal},    
  48.     };    
  49.        
  50.     int register_android_server_GpioService(JNIEnv *env) {    
  51.         return jniRegisterNativeMethods(env, "com/android/server/GpioService", method_table, NELEM(method_table));    
  52.     }    
  53. };    

其中GPIO_HARDWARE_MODULE_ID是在hardware/gpio.h中定义的,初始化时通过hw_get_module方法加载硬件层模块。 修改当前目录下的onload.cpp:

在namespace android中加入函数声明:

 

[javascript] view plain copy
 
  1. int register_android_server_GpioService(JNIEnv* env);  

在JNI_Onload中加入函数调用:

 

 

[javascript] view plain copy
 
  1. register_android_server_GpioService(env);  

修改frameworks/base/core/jni下的AndroidRuntime.cpp,在namespace android中加入声明:

 

 

[javascript] view plain copy
 
  1. extern int register_android_server_GpioService(JNIEnv* env);  

 

修改services/jni目录下的Android.mk文件:

在LOCAL_SRC_FILES加入:

 

[javascript] view plain copy
 
  1. com_android_server_GpioService.cpp \  

编译JNI方法:

 

 

[javascript] view plain copy
 
  1. make TARGET_PRODUCT=am335xevm_sk -j8 OMAPES=4.x  

如果成功,则生成libandroid_servers.so

 

[javascript] view plain copy
 
  1. out/target/product/am335xevm_sk/obj/lib/libandroid_servers.so    

JNI方法编译完成后,就可以通过android硬件服务GpioService来调用JNI方法,以此来调用硬件抽象层访问底层硬件。

posted on 2018-01-10 13:44  无网不进  阅读(280)  评论(0)    收藏  举报