Android 系统开发系列三

来源:互联网 发布:淘宝和田玉店铺 编辑:程序博客网 时间:2024/05/22 14:50
今天写HAL硬件抽象层

1、添加HAL头文件

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

[cpp] view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/include/hardware# gedit 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  

这里按照Android硬件抽象层规范的要求,分别定义模块ID、模块结构体以及硬件接口结构体。

2、实现HAL

进入android-4.0.4_r1.2/hardware/libhardware/modules 目录,创建 ttt 目录:

[cpp] view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/modules# mkdir ttt  

进入到新创建的ttt目录下面,并创建 ttt.c 文件:

[cpp] view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/modules/ttt# gedit ttt.c  

其内容如下:

[cpp] view plain copy
  1. #define LOG_TAG     "TTTStub"  
  2.   
  3. #include <hardware/hardware.h>  
  4. #include <hardware/ttt.h>  
  5. #include <fcntl.h>  
  6. #include <errno.h>  
  7. #include <cutils/log.h>  
  8. #include <cutils/atomic.h>  
  9.   
  10. #define DEVICE_NAME "/dev/ttt"  
  11. #define MODULE_NAME "TTT"  
  12. #define MODULE_AUTHOR   "brantyou@qq.com"  
  13.   
  14. // open/close device interface  
  15. static int ttt_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);  
  16. static int ttt_device_close(struct hw_device_t* device);  
  17.   
  18. // device interfaces  
  19. static int ttt_set_val(struct ttt_device_t* dev, int val);  
  20. static int ttt_get_val(struct ttt_device_t* dev, int* val);  
  21.   
  22. // module methods  
  23. static struct hw_module_methods_t ttt_module_methods = {  
  24.     open: ttt_device_open  
  25. };  
  26.   
  27. // module variables  
  28. const struct ttt_module_t HAL_MODULE_INFO_SYM = {  
  29.     common: {  
  30.         tag: HARDWARE_MODULE_TAG,  
  31.         version_major: 1,  
  32.         version_minor: 0,  
  33.         id: HELLO_HARDWARE_MODULE_ID,  
  34.         name: MODULE_NAME,  
  35.         author: MODULE_AUTHOR,  
  36.         methods: &ttt_module_methods,  
  37.     }  
  38. };  
  39.   
  40.   
  41. // * device set value interface  
  42. static int ttt_set_val(struct ttt_device_t* dev, int val)  
  43. {  
  44.     LOGI("TTT Stub: set value %d to device.", val);  
  45.   
  46.     write(dev->fd, &val, sizeof(val));  
  47.   
  48.     return 0;  
  49. }  
  50.   
  51. // * device get value interface  
  52. static int ttt_get_val(struct ttt_device_t* dev, int* val)  
  53. {  
  54.     if(!val){  
  55.         LOGE("TTT Stub: error val pointer.");  
  56.         return -EFAULT;  
  57.     }  
  58.   
  59.     read(dev->fd, val, sizeof(*val));  
  60.     LOGI("TTT Stub: get value %d from device.", *val);  
  61.   
  62.     return 0;  
  63. }  
  64.   
  65. // * close device interface  
  66. static int ttt_device_close(struct hw_device_t* device)  
  67. {  
  68.     struct ttt_device_t* ttt_device = (struct ttt_device_t*)device;  
  69.   
  70.     if(ttt_device){  
  71.         close(ttt_device->fd);  
  72.         free(ttt_device);  
  73.     }  
  74.   
  75.     return 0;  
  76. }  
  77.   
  78. // * open device interface  
  79. static int ttt_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device)  
  80. {  
  81.     struct ttt_device_t* dev;  
  82.     dev = (struct ttt_device_t*)malloc( sizeof(struct ttt_device_t) );  
  83.   
  84.     if(!dev){  
  85.         LOGE("TTT stub: failed to alloc space");  
  86.         return -EFAULT;  
  87.     }  
  88.   
  89.     memset(dev, 0, sizeof(struct ttt_device_t));  
  90.     dev->common.tag = HARDWARE_DEVICE_TAG;  
  91.     dev->common.version = 0;  
  92.     dev->common.module = (hw_module_t*)module;  
  93.     dev->common.close = ttt_device_close;  
  94.     dev->set_val = ttt_set_val;  
  95.     dev->get_val = ttt_get_val;  
  96.   
  97.     if( (dev->fd = open(DEVICE_NAME, O_RDWR)) == -1){  
  98.         LOGE("TTT Stub: failed to open /dev/ttt -- %s.", strerror(errno));  
  99.         free(dev);  
  100.         return -EFAULT;  
  101.     }  
  102.   
  103.     *device = &(dev->common);  
  104.     LOGI("TTT Stub: open /dev/ttt successfully.");  
  105.   
  106.     return 0;  
  107. }  


在该目录下创建对应的Android.mk文件:

[cpp] view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/modules/ttt# gedit Android.mk  

其内容如下:

[cpp] view plain copy
  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. LOCAL_MODULE_TAGS := optional  
  4. LOCAL_PRELINK_MODULE := false  
  5. LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw  
  6. LOCAL_SHARED_LIBRARIES := liblog  
  7. LOCAL_SRC_FILES := ttt.c  
  8. LOCAL_MODULE := ttt.default  
  9. include $(BUILD_SHARED_LIBRARY)  

 


3、添加权限

由于设备文件是在内核驱动里面通过 device_create 创建的,而 device_create 创建的设备文件默认只有 root 用户

可读写,而 ttt_device_open 一般是由上层APP来调用的,这些 APP 一般不具有 root 权限,这时候就有可能导致打开设备文件失败,提示类似于:

Permission denied.

解决办法是类似 linux 的udev 规则,

进入到 android-4.0.4_r1.2/system/core/rootdir 目录,打开 uenentd.rc 文件:

[cpp] view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/system/core/rootdir# gedit ueventd.rc  

在里面添加一句:

[cpp] view plain copy
  1. /dev/ttt                  0666   root       root  



4、开始编译


执行命令如下:

[cpp] view plain copy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm hardware/libhardware/modules/ttt  
  2. ============================================  
  3. PLATFORM_VERSION_CODENAME=REL  
  4. PLATFORM_VERSION=4.0.4  
  5. TARGET_PRODUCT=full_smdkv210  
  6. TARGET_BUILD_VARIANT=eng  
  7. TARGET_BUILD_TYPE=release  
  8. TARGET_BUILD_APPS=  
  9. TARGET_ARCH=arm  
  10. TARGET_ARCH_VARIANT=armv7-a-neon  
  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: ttt.default <= hardware/libhardware/modules/ttt/ttt.c  
  18. target SharedLib: ttt.default (out/target/product/smdkv210/obj/SHARED_LIBRARIES/ttt.default_intermediates/LINKED/ttt.default.so)  
  19. target Symbolic: ttt.default (out/target/product/smdkv210/symbols/system/lib/hw/ttt.default.so)  
  20. target Strip: ttt.default (out/target/product/smdkv210/obj/lib/ttt.default.so)  
  21. Install: out/target/product/smdkv210/system/lib/hw/ttt.default.so  
  22. make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”  
  23. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#   

重新打包system.img:

[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_smdkv210  
  6. TARGET_BUILD_VARIANT=eng  
  7. TARGET_BUILD_TYPE=release  
  8. TARGET_BUILD_APPS=  
  9. TARGET_ARCH=arm  
  10. TARGET_ARCH_VARIANT=armv7-a-neon  
  11. HOST_ARCH=x86  
  12. HOST_OS=linux  
  13. HOST_BUILD_TYPE=release  
  14. BUILD_ID=IMM76I  
  15. ============================================  
  16. build/core/Makefile:25: 警告:覆盖关于目标“out/target/product/smdkv210/system/bin/pppd”的命令  
  17. build/core/base_rules.mk:523: 警告:忽略关于目标“out/target/product/smdkv210/system/bin/pppd”的旧命令  
  18. make snod: ignoring dependencies  
  19. Target system fs image: out/target/product/smdkv210/system.img  
  20. out/target/product/smdkv210/system.img total size is 150853824  
  21. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#   




 

到此,HAL层的就编写完了,下一篇就是编写对应的JNI接口了。

0 0