Android 驱动开发系列四

时隔多日,终于都抽出时间来写blog了。废话不多说,接着上一篇,这里将介绍如何编写HAL层(硬件抽象层)对应的JNI方法。

这里提到的都是在ICS源码里编译的。

 

1、定义JNI层接口

进入到android-4.0.4_r1.2/hardware/libhardware/include/hardware目录,并创建 ttt.h 文件,内容如下:

[cpp]  view plain copy
  1. #ifndef ANDROID_TTT_INTERFACE_H  
  2. #define ANDROID_TTT_INTERFACE_H  
  3. #include <hardware/hardware.h>  
  4.   
  5. __BEGIN_DECLS  
  6.   
  7. // 定义模块ID  
  8. #define HELLO_HARDWARE_MODULE_ID    "ttt"  
  9.   
  10. // 硬件模块结构体  
  11. struct ttt_module_t{  
  12.     struct hw_module_t common;  
  13. };  
  14.   
  15. // hardware interface struct  
  16. struct ttt_device_t{  
  17.     struct hw_device_t common;  
  18.     int fd;  
  19.     int(*set_val)(struct ttt_device_t* dev, int val);  
  20.     int(*get_val)(struct ttt_device_t* dev, int* val);  
  21. };  
  22.   
  23. __END_DECLS  
  24.   
  25.   
  26. #endif  

 

2、实现JNI层接口功能

进入到android-4.0.4_r1.2/frameworks/base/services/jni目录,并创建com_android_server_TTTService.cpp文件,其内容如下:

[cpp]  view plain copy
  1. #define LOG_TAG     "TTTService"  
  2.   
  3. #include "jni.h"  
  4. #include "JNIHelp.h"  
  5. #include "android_runtime/AndroidRuntime.h"  
  6. #include <utils/misc.h>  
  7. #include <utils/Log.h>  
  8. #include <hardware/hardware.h>  
  9. #include <hardware/ttt.h>  
  10. #include <stdio.h>  
  11.   
  12. namespace android  
  13. {  
  14.     struct ttt_device_t* ttt_device = NULL;  
  15.   
  16.     // through the HAL interface to set the register value  
  17.     static void ttt_setVal(JNIEnv* env, jobject clazz, jint value){  
  18.         int val = value;  
  19.         LOGI("TTT JNI: set value %d to device.", val);  
  20.         if(!ttt_device){  
  21.             LOGI("TTT JNI: device is not open.");  
  22.             return;  
  23.         }  
  24.   
  25.         ttt_device->set_val(ttt_device, val);  
  26.     }  
  27.   
  28.     // through the HAL interface to read the register value  
  29.     static jint ttt_getVal(JNIEnv* env, jobject clazz){  
  30.         int val = 0;  
  31.         if(!ttt_device){  
  32.             LOGI("TTT JNI: device is not open.");  
  33.             return val;  
  34.         }  
  35.         ttt_device->get_val(ttt_device, &val);  
  36.   
  37.         LOGI("TTT JNI: get value %d from device.", val);  
  38.   
  39.         return val;  
  40.     }  
  41.   
  42.     // through the HAL interface to open the hardware device  
  43.     static inline int ttt_device_open(const hw_module_t* module, struct ttt_device_t** device){  
  44.         return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);  
  45.     }  
  46.   
  47.     // throught the hardware module ID to load the HAL module and open the device  
  48.     static jboolean ttt_init(JNIEnv* env, jclass clazz){  
  49.         ttt_module_t* module;  
  50.   
  51.         LOGI("TTT JNI: initializing...");  
  52.         if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0){  
  53.             LOGI("TTT JNI: ttt stub found.");  
  54.             if(ttt_device_open(&(module->common), &ttt_device) == 0){  
  55.                 LOGI("TTT JNI: ttt device is open.");  
  56.                 return 0;  
  57.             }  
  58.             LOGE("TTT JNI: failed to open ttt device.");  
  59.             return -1;  
  60.         }  
  61.   
  62.         LOGE("TTT JNI: failed to get ttt stub module.");  
  63.         return -1;  
  64.     }  
  65.   
  66.     // JNI methods table  
  67.     static const JNINativeMethod method_table[] = {  
  68.         {"init_native""()Z", (void*)ttt_init},  
  69.         {"setVal_native""(I)V", (void*)ttt_setVal},  
  70.         {"getVal_native""()I", (void*)ttt_getVal},  
  71.     };  
  72.   
  73.     // regist JNI method  
  74.     int register_android_server_TTTService(JNIEnv* env){  
  75.         return jniRegisterNativeMethods(env, "com/android/server/TTTService", method_table, NELEM(method_table));  
  76.     }  
  77. };  


 

3、添加JNI初始化调用

修改android-4.0.4_r1.2/frameworks/base/services/jni目录下的 onload.cpp 文件,在 JNI_OnLoad函数中的return之前添加下面一句:

[cpp]  view plain copy
  1. register_android_server_TTTService(env);  

同时,在该文件中的namespace中添加下面一句声明:

[cpp]  view plain copy
  1. int register_android_server_TTTService(JNIEnv* env);  

 

这样,在系统初始化时,就会调用register_android_server_TTTService方法来加载JNI方法了。

 

4、添加编译JNI的配置

修改android-4.0.4_r1.2/frameworks/base/services/jni目录下的 Android.mk 文件,在 LOCAL_SRC_FILES 变量中添加下面一行:

[cpp]  view plain copy
  1. com_android_server_TTTService.cpp \  

这里是添加编译配置。


5、开始编译

[cpp]  view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# . build/envsetup.sh   
  2. including device/moto/stingray/vendorsetup.sh  
  3. including device/moto/wingray/vendorsetup.sh  
  4. including device/samsung/crespo4g/vendorsetup.sh  
  5. including device/samsung/crespo/vendorsetup.sh  
  6. including device/samsung/maguro/vendorsetup.sh  
  7. including device/samsung/smdkc110/vendorsetup.sh  
  8. including device/samsung/smdkv210/vendorsetup.sh  
  9. including device/samsung/torospr/vendorsetup.sh  
  10. including device/samsung/toro/vendorsetup.sh  
  11. including device/samsung/tuna/vendorsetup.sh  
  12. including device/ti/panda/vendorsetup.sh  
  13. including sdk/bash_completion/adb.bash  
  14. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#  
[cpp]  view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm frameworks/base/services/jni  
  2. ============================================  
  3. PLATFORM_VERSION_CODENAME=REL  
  4. PLATFORM_VERSION=4.0.4  
  5. TARGET_PRODUCT=full  
  6. TARGET_BUILD_VARIANT=eng  
  7. TARGET_BUILD_TYPE=release  
  8. TARGET_BUILD_APPS=  
  9. TARGET_ARCH=arm  
  10. TARGET_ARCH_VARIANT=armv7-a  
  11. HOST_ARCH=x86  
  12. HOST_OS=linux  
  13. HOST_BUILD_TYPE=release  
  14. BUILD_ID=IMM76I  
  15. ============================================  
  16. make:进入目录'/home/brantyou/workspace/android-4.0.4_r1.2'  
  17. target thumb C++: libandroid_servers <= frameworks/base/services/jni/com_android_server_HelloService.cpp  
  18. target thumb C++: libandroid_servers <= frameworks/base/services/jni/com_android_server_TTTService.cpp  
  19. target thumb C++: libandroid_servers <= frameworks/base/services/jni/onload.cpp  
  20. make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so”需要的目标“out/target/product/generic/obj/lib/libsystem_server.so”。 停止。  
  21. make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”  
  22. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#   

矮油~~~这里出错了,提示没有找到 libsystem_server.so 文件。
执行下面的命令,生成 libsystem_server.so 文件:

[cpp]  view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make libsystem_server  

生成之后的提示:

[cpp]  view plain copy
  1. Install: out/target/product/generic/system/lib/libvorbisidec.so  
  2. Install: out/target/product/generic/system/lib/libstagefright_yuv.so  
  3. Install: out/target/product/generic/system/lib/libdrmframework.so  
  4. Install: out/target/product/generic/system/lib/libchromium_net.so  
  5. Install: out/target/product/generic/system/lib/libstagefright_amrnb_common.so  
  6. Install: out/target/product/generic/system/lib/libstagefright_enc_common.so  
  7. Install: out/target/product/generic/system/lib/libstagefright_avc_common.so  
  8. Install: out/target/product/generic/system/lib/libstagefright.so  
  9. Install: out/target/product/generic/system/lib/libstagefright_omx.so  
  10. Install: out/target/product/generic/system/lib/libmediaplayerservice.so  
  11. Install: out/target/product/generic/system/lib/libinput.so  
  12. Install: out/target/product/generic/system/lib/libsystem_server.so  
  13. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#   

好了,这个问题解决了,我们继续编译这个JNI。

[cpp]  view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm frameworks/base/services/jni  
  2. ============================================  
  3. PLATFORM_VERSION_CODENAME=REL  
  4. PLATFORM_VERSION=4.0.4  
  5. TARGET_PRODUCT=full  
  6. TARGET_BUILD_VARIANT=eng  
  7. TARGET_BUILD_TYPE=release  
  8. TARGET_BUILD_APPS=  
  9. TARGET_ARCH=arm  
  10. TARGET_ARCH_VARIANT=armv7-a  
  11. HOST_ARCH=x86  
  12. HOST_OS=linux  
  13. HOST_BUILD_TYPE=release  
  14. BUILD_ID=IMM76I  
  15. ============================================  
  16. make:进入目录'/home/brantyou/workspace/android-4.0.4_r1.2'  
  17. target SharedLib: libandroid_servers (out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so)  
  18. target Symbolic: libandroid_servers (out/target/product/generic/symbols/system/lib/libandroid_servers.so)  
  19. target Strip: libandroid_servers (out/target/product/generic/obj/lib/libandroid_servers.so)  
  20. Install: out/target/product/generic/system/lib/libandroid_servers.so  
  21. make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”  
  22. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#  

很好,这一次已经顺利的编译完了。


下面我们需要重新打包这个 system.img,包我们编写的JNI方法包含进去:

[cpp]  view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make snod  
  2. ============================================  
  3. PLATFORM_VERSION_CODENAME=REL  
  4. PLATFORM_VERSION=4.0.4  
  5. TARGET_PRODUCT=full  
  6. TARGET_BUILD_VARIANT=eng  
  7. TARGET_BUILD_TYPE=release  
  8. TARGET_BUILD_APPS=  
  9. TARGET_ARCH=arm  
  10. TARGET_ARCH_VARIANT=armv7-a  
  11. HOST_ARCH=x86  
  12. HOST_OS=linux  
  13. HOST_BUILD_TYPE=release  
  14. BUILD_ID=IMM76I  
  15. ============================================  
  16. make snod: ignoring dependencies  
  17. Target system fs image: out/target/product/generic/system.img  
  18. out/target/product/generic/system.img total size is 44107008  
  19. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#   

这样就成功的把我们编写的JNI打包到 system.img中了。

 

这章到此结束,下一章将介绍,如何基于JNI接口编写对应的服务和编写对应的Android程序来访问服务。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值