今天写HAL硬件抽象层

1、添加HAL头文件

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

[cpp] view plaincopy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/include/hardware# gedit ttt.h

文件内容如下:

[cpp] view plaincopy
  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 plaincopy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/modules# mkdir ttt

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

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

其内容如下:

[cpp] view plaincopy
  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 plaincopy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/hardware/libhardware/modules/ttt# gedit Android.mk

其内容如下:

[cpp] view plaincopy
  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 plaincopy
  1. root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2/system/core/rootdir# gedit ueventd.rc

在里面添加一句:

[cpp] view plaincopy
  1. /dev/ttt                  0666   root       root

4、开始编译

执行命令如下:

[cpp] view plaincopy
  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 plaincopy
  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系统开发篇(三) —— Android AOSP 9.0源码的同步与编译

    上回书我们说到,Ubuntu系统的安装和配置,既然是Android系统的开发,那我们就要有Android系统,那好,目标很明确,接下来我们就来操作,看看源码是怎么来的 一.Android 源码下载(同 ...

  2. Android 系统开发系列一

    最近开始接触Android底层的开发,这里面将记录开发一个驱动以及到测试的全过程. 首先,需要搭建Android的开发环境.我这里采用的是Ubuntu 11.04 64bit的系统,里面使用gcc-4 ...

  3. Android 系统开发系列(1):Android 12 源代码下载、编译和刷机

    Android 12 正式版 已经发布:https://mp.weixin.qq.com/s/OiFSWEnc-0N2z7JYWTJluw 本文就带大家下载和编译最新的 Android 12 代码,本 ...

  4. Android 系统开发系列四

    这里将介绍如何编写HAL层(硬件抽象层)对应的JNI方法. 1.定义JNI层接口 进入到android-4.0.4_r1.2/hardware/libhardware/include/hardware ...

  5. Android 系统开发系列二

    这一章主要是讲如何测试驱动. 1.驱动的简单测试 在上一篇文章中,我们已经把添加驱动模块做完了,并把驱动下载到了板子上.下面将介绍一下如何测试驱动是否正常. 这个ttt驱动,我们实现了一个读.一个写的 ...

  6. Android 驱动开发系列三

    写blog的时候,发现跳章了,HAL硬件抽象层都没有写就到JNI了,这里补回来. 1.添加HAL头文件 进入到 android-4.0.4_r1.2/hardware/libhardware/incl ...

  7. [视频教程] KBEngine mmo手游开发系列(三) - 角色技能与怪物系统

    KBEngine mmo手游开发系列(三)-角色技能与怪物系统 课程链接:https://edu.51cto.com/sd/21044 本课程为KBEngine mmo手游开发系列的第三个课程,本课程 ...

  8. Android系统开发 ----- 系统服务开发

    系列文章目录 Android系统启动 ---- 主要流程类_MrDarly的博客-CSDN博客Android系统启动Zygote关系主要的类https://blog.csdn.net/weixin_6 ...

  9. Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

    Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...

最新文章

  1. 进程间程序替换和minishell
  2. word List 13
  3. mysql7.5安装教程_CentOS7.5下yum安装MySQL8图文教程
  4. 强烈推荐《价值:我对投资的思考》
  5. 工信部:2020年启动5G商用
  6. 永磁同步电机转子磁链_采用冻结磁导率的瞬态场永磁同步电机交直轴电感计算...
  7. Rust: 如何在Windows下Atom中配置Rust环境?
  8. android studio应用开发案例,Android应用开发案例教程(Android Studio版).pptx
  9. 无线通信设备安装工程概预算编制_安装造价工程 电气安装预算编制
  10. md5加密算法使用流程
  11. 用php求常见图形的面积,小学常见图形面积公式:菱形公式
  12. 基于android终端的物联网医药物流管理系统设计公司,基于Android终端的物联网物流管理系统的设计与实现.pdf...
  13. autoCAD恐吓式销售_恐吓式软文的例子 恐吓式软文营销案例分享
  14. NVIDIA Jetson TK1 rosrun rviz segmentation fault的解决方法
  15. 计算机开机桌面黑屏怎么办,小编教你电脑启动后黑屏该怎么办
  16. windows的局域网渗透
  17. UnityShader-高斯模糊
  18. HTML游戏实战之《跳楼梯》
  19. sca java_SCA客户端以及基于Java的模型实现(一)
  20. python车牌识别系统+车辆管理+计费系统(图像识别)django框架 计算机毕业设计

热门文章

  1. 大话说github建立里程碑(SE)
  2. 图像处理------简单脸谱检测算法
  3. 记一次消息总线的打造 - McKay - 博客园
  4. 【转载】spring mvc 使用session
  5. 移动开发 Jetpack Compose 组件布局
  6. Apache Tika 内容抽取工具集合
  7. 数据结构c语言版实验报告2,数据结构(C语言版) 实验报告 (2)
  8. Matlab中插值函数使用
  9. python 高性能http服务器_Python高性能HTTP客户端
  10. 自学考试c语言真题,自学考试《C语言程序设计》复习试题及答案