Android 标准的硬件驱动分为两个部分,一个是运行在linux内核里的硬件驱动,而另外一部分是运行在用户空间的硬件抽象层。采用这种方法,就可以使系统具有硬件无关性,也保护了部分厂商的利益。在 Android 从硬件到应用:一步一步向上爬 1 -- 从零编写底层硬件驱动程序中已经有了编写硬件驱动到linux内核里的步骤,下面就要接着这个工程去看看怎么在硬件抽象层增加硬件模块和我们的内核驱动程序进行交互,完成硬件控制。

进入hardware/libhardware/include/hardware目录,新建gpio.h:

#ifndef ANDROID_GPIO_INTERFACE_H  #define ANDROID_GPIO_INTERFACE_H  #include <hardware/hardware.h>        __BEGIN_DECLS        /*module ID*/  #define GPIO_HARDWARE_MODULE_ID "gpio"  /*module struct*/  struct gpio_module_t {struct hw_module_t common;  };       /*interface struct*/  struct gpio_device_t {struct hw_device_t common;  int fd;  int (*set_val)(struct gpio_device_t* dev, int val);  int (*get_val)(struct gpio_device_t* dev, int* val);  }; __END_DECLS#endif  
其中set_val和get_val是HAL层向上层应用提供的API接口。

cd到hardware/libhardware/modules目录,新建gpio目录,在里面新建gpio.c文件:

#include <hardware/hardware.h>  #include <hardware/gpio.h>  #include <fcntl.h>  #include <errno.h>  #include <cutils/log.h>  #include <cutils/atomic.h>  #define DEVICE_NAME "/dev/AdrIO"  #define MODULE_NAME "Gpio"  //open and closestatic int gpio_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);  static int gpio_device_close(struct hw_device_t* device);  //device accessstatic int gpio_set_val(struct gpio_device_t* dev, int val);  static int gpio_get_val(struct gpio_device_t* dev, int* val);  static struct hw_module_methods_t gpio_module_methods = {      open: gpio_device_open  };  struct gpio_module_t HAL_MODULE_INFO_SYM = {      common: {          tag: HARDWARE_MODULE_TAG,          version_major: 1,          version_minor: 0,          id: GPIO_HARDWARE_MODULE_ID,          name: MODULE_NAME,          author: "HAL",          methods: &gpio_module_methods, }  }; static int gpio_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {  struct gpio_device_t* dev;dev = (struct gpio_device_t*)malloc(sizeof(struct gpio_device_t));  memset(dev, 0, sizeof(struct gpio_device_t));  dev->common.tag = HARDWARE_DEVICE_TAG;  dev->common.version = 0;  dev->common.module = (hw_module_t*)module;  dev->common.close = gpio_device_close;  dev->set_val = gpio_set_val;dev->get_val = gpio_get_val;  if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {  LOGE("gpio: failed to open /dev/AdrIO -- %s.", strerror(errno));free(dev);  return -EFAULT;  }  *device = &(dev->common);  return 0;  }  static int gpio_device_close(struct hw_device_t* device) {  struct gpio_device_t* gpio_device = (struct gpio_device_t*)device;  if(gpio_device) {      close(gpio_device->fd);      free(gpio_device);  }    return 0;  }  static int gpio_set_val(struct gpio_device_t* dev, int val) {  LOGI("gpio: set value %d to device.", val);  write(dev->fd, &val, sizeof(val));  return 0;  }  static int gpio_get_val(struct gpio_device_t* dev, int* val) {  return 0;}
为了防止调用时出现 Permission denied的情况:

打开am335xevm文件系统根目录rootfs,打开ueventd.rc添加:

/dev/AdrIO  0666 root root

该文件并不会创建设备节点,而是当有设备节点产生的时候,eventd 会根据这个数据库设置设备的权限。

修改hardware/libhardware/modules目录下Android.mk在harware_modules :=后面加上“gpio”

在gpio目录中继续添加Android.mk文件:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_PRELINK_MODULE := falseLOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hwLOCAL_SHARED_LIBRARIES := liblogLOCAL_SRC_FILES := gpio.cLOCAL_MODULE := gpio.defaultinclude $(BUILD_SHARED_LIBRARY)

编译HAL层:

make TARGET_PRODUCT=am335xevm_sk -j8 OMAPES=4.x

如果出现错误,参考:

没有规则可以创建 /lib/liblog.so

如果成功,就可以生成 gpio.default.so

out/target/product/am335xevm_sk/obj/lib/gpio.default.so
这个就是我们需要的硬件抽象层模块,这一步完成之后,还要接着向上走,最终完成硬件调用。

更多相关文章

  1. 原有Android项目集成RN入坑计(一)
  2. Android的图形显示原理(GDI)一
  3. android用NFS的形式挂载工作.
  4. Android(安卓)studio 43 文件存储到sdcard download文件夹下
  5. Android(安卓)SDK 源码下载,eclipse关联代码
  6. android如何读取assets目录下的资源
  7. android openssl 编译+demo
  8. Android(安卓)环境搭建,Helloworld以及常见错误处理,最新版哦
  9. android 树形目录

随机推荐

  1. ContentProvider回顾
  2. Android(安卓)Studio 串口jni开发
  3. Android(安卓)SurfaceView使用详解(很好的
  4. context上下文
  5. Android(安卓)使用dalvikvm 执行字节码
  6. Android开发一些常见问题
  7. Gradle 安装以及查看jar文件本地的存储位
  8. Android(安卓)Studio安装并使用Kotlin插
  9. android中Content Provider初步
  10. android学习之ListView如何使用