Android from hardware to application: Step by Step 4-use the JNI method to tune the hardware driver
In Android, java applications call the hardware abstraction layer module through the JNI method, from hardware to application in Android: Step by Step 3 -- access the hardware driver in the Hardware Abstraction Layer
We have compiled the hardware abstraction layer module. Next we will begin to compile the jni method for the hal layer to provide services for the upper layer.
Cd to the frameworks/base/services/jni directory to create a com_android_server_GpioService.cpp file:
#include "jni.h" #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include
#include
#include
#include
#include
namespace android { struct android_gpio_device_t* android_gpio_device = NULL; static void android_gpio_setVal(JNIEnv* env, jobject clazz, jint value) { int val = value; android_gpio_device->set_val(android_gpio_device, val); } static jint android_gpio_getVal(JNIEnv* env, jobject clazz) { return 0; } static inline int android_gpio_device_open(const hw_module_t* module, struct android_gpio_device_t** device) { return module->methods->open(module, ANDROID_GPIO_HARDWARE_MODULE_ID, (struct hw_device_t**)device); } static jboolean android_gpio_init(JNIEnv* env, jclass clazz) { android_gpio_module_t* module; if(hw_get_module(ANDROID_GPIO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) { if(android_gpio_device_open(&(module->common), &android_gpio_device) == 0){ return 0; } return -1; } return -1; } static const JNINativeMethod method_table[] = { {"init_native", "()Z", (void*)android_gpio_init}, {"setVal_native", "(I)V", (void*)android_gpio_setVal}, {"getVal_native", "()I", (void*)android_gpio_getVal}, }; int register_android_server_GpioService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/GpioService", method_table, NELEM(method_table)); } };
ANDROID_GPIO_HARDWARE_MODULE_ID is defined in hardware/android_gpio.h. during initialization, the hardware layer module is loaded using the hw_get_module method. Modify onload. cpp in the current directory:
Add the function declaration to namespace android:
int register_android_server_GpioService(JNIEnv* env);
Add a function call to JNI_Onload:
register_android_server_GpioService(env);
Modify AndroidRuntime. cpp under frameworks/base/core/jni and add the Declaration in namespace android:
extern int register_android_server_GpioService(JNIEnv* env);
Modify the Android. mk file in the current directory:
Add LOCAL_SRC_FILES:
com_android_server_GpioService.cpp \
Compile the JNI method:
mmm frameworks/base/services/jni
If libandroid_runtime.so, libsystem_server.so, and libandroid_servers.so are missing, run:
make libandroid_runtime
make libsystem_server
make libandroid_servers
After the JNI method is compiled, you can use the android hardware service GpioService to call the JNI method to call the hardware abstraction layer to access the underlying hardware.