写blog的时候,发现跳章了,HAL硬件抽象层都没有写就到JNI了,这里补回来。

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

在该目录下创建对应的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接口了。

Android 驱动开发系列三相关推荐

  1. Android 驱动开发系列二

    最近琐碎事太多了,都没什么时间来写blog.现在继续写这个android驱动的开发调试 这一章主要是讲如何测试驱动. 1.驱动的简单测试 在上一篇文章中,我们已经把添加驱动模块做完了,并把驱动下载到了 ...

  2. DJYOS驱动开发系列三:基于DJYOS的SPI驱动编写指导手册

    1.贡献者列表 深圳市秦简计算机系统有限公司DJYOS驱动开发团队. 2.概述 DJYOS的DjyBus总线模型为IIC.SPI之类的器件提供统一的访问接口,SPIBUS模块是DjyBus模块的一个子 ...

  3. Android驱动开发第三章随想

    本章主要是以FS_S5PC100开发版为例讲解Android系统移植开发平台的使用,首先讲解如何搭建FS_S5PC100平台开发环境,包括他的安装和使用: 一.将linux-2.6.29内核镜像zIm ...

  4. Android 系统开发系列三

    今天写HAL硬件抽象层 1.添加HAL头文件 进入到 android-4.0.4_r1.2/hardware/libhardware/include/hardware 目录,创建 ttt.h 文件: ...

  5. 【转】Android 驱动开发系列四

    原文网址:http://www.2cto.com/kf/201304/202040.html 时隔多日,终于都抽出时间来写blog了.废话不多说,接着上一篇,这里将介绍如何编写HAL层(硬件抽象层)对 ...

  6. Android 驱动开发系列五

    转至:http://blog.csdn.net/brantyou/article/details/8782396 这一篇将说到 如何为JNI接口(Frameworks层)添加对应的service访问服 ...

  7. Android驱动开发之陀螺仪(三)

    Android驱动开发之陀螺仪(二) 五.安卓hal层驱动数据读取 使能陀螺仪后,由于我配置的是原始数据准备中断,所以陀螺仪数据一旦准备好,就会发送中断信号,之前在第二章已经分析过中断的注册流程,这里 ...

  8. Android驱动入门系列(一)

    Android驱动入门系列(一)   -- Android驱动简介及编写第一个Android驱动 以下文章参考网上搜到的<Android驱动开发全过程(有图有真相)>一文,其中根据自己的实 ...

  9. 初入android驱动开发之字符设备(一)

    大学毕业,初入公司,招进去的是android驱动开发工程师的岗位,那时候刚进去,首先学到的就是如何搭建kernel.android的编译环境,然后就是了解如何刷设备以及一些最基本的工具.如adb.fa ...

最新文章

  1. ES6之路第十二篇:Promise对象
  2. python豆瓣爬虫爬取评论做成词云
  3. 百度发布全新桌面版机器学习开发环境,12月赠送免费GPU算力
  4. matlab 二值化_撸了一份 ostu二值化,需要的小伙伴请拿走
  5. maven snapshot依赖 打包_Maven教程2:Maven项目构建过程练习
  6. 具有NetBeans,嵌入式GlassFish,JPA和MySQL数据源的Arquillian
  7. 理论基础 —— 排序 —— 计数排序
  8. Yii2.0修改默认控制器
  9. Nodejs最好的ORM - TypeORM
  10. Linux 配置网络
  11. 字符串匹配KMP算法的讲解C++
  12. UILabel「行距,首行缩进」
  13. ue4是什么意思_UE4 C++基础教程 - 资源常见名词解释
  14. 2021下半年最新编程培训机构排名出炉!
  15. vivado2017.4开发vc707(virtex7)(一)上电调试
  16. cisco anyConnect 不用每次输入密码的办法
  17. Excel 多列条件查找
  18. html输入某天得到周几,HTML “input week年周”输入控件简介说明
  19. 正面杠腾讯音乐与网易云音乐,抖音与快手谁能“弯道超车“?
  20. redhat开机自动连接网络设置

热门文章

  1. 倍增收入,大学生兼职经验分享
  2. instr()字符查找函数
  3. 用 WeixinJSBridge.invoke函数实现微信分享标题和文案
  4. 了解和使用keystone(五)获取token
  5. UE4 用C++让Pawn动起来
  6. hihocoder [Offer收割]编程练习赛19
  7. gff文件_GFF3格式介绍 | Public Library of Bioinformatics
  8. 带你玩转Jetson Xavier NX系列教程 | Xavier NX 环境变量配置,风扇控制以及Jtop安装
  9. linux thp 参数,THP关闭方法-Transparent Pages
  10. 结巴(jieba)分词 java 实现