Android 从硬件到应用:一步一步向上爬 3 -- 硬件抽象层访问硬件驱动

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

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

#ifndef ANDROID_ANDROID_GPIO_INTERFACE_H
#define ANDROID_ANDROID_GPIO_INTERFACE_H
#include <hardware/hardware.h>  

__BEGIN_DECLS  

/*module ID*/
#define ANDROID_GPIO_HARDWARE_MODULE_ID "android_gpio"
/*module struct*/
struct android_gpio_module_t {
	struct hw_module_t common;
};
/*interface struct*/
struct android_gpio_device_t {
	struct hw_device_t common;
	int fd;
	int (*set_val)(struct android_gpio_device_t* dev, int val);
	int (*get_val)(struct android_gpio_device_t* dev, int* val);
};
__END_DECLS
#endif  

其中set_val和get_val是HAL层向上层应用提供的API接口。

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

#include <hardware/hardware.h>
#include <hardware/android_gpio.h>
#include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#define DEVICE_NAME "/dev/AdrIO"
#define MODULE_NAME "Android_gpio"  

//open and close
static int android_gpio_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);
static int android_gpio_device_close(struct hw_device_t* device);
//device access
static int android_gpio_set_val(struct android_gpio_device_t* dev, int val);
static int android_gpio_get_val(struct android_gpio_device_t* dev, int* val);  

static struct hw_module_methods_t android_gpio_module_methods = {
    open: android_gpio_device_open
};  

struct android_gpio_module_t HAL_MODULE_INFO_SYM = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        version_major: 1,
        version_minor: 0,
        id: ANDROID_GPIO_HARDWARE_MODULE_ID,
        name: MODULE_NAME,
        author: "HAL",
        methods: &android_gpio_module_methods, }
}; 

static int android_gpio_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device)
{
	struct android_gpio_device_t* dev;
	dev = (struct android_gpio_device_t*)malloc(sizeof(struct android_gpio_device_t));
	memset(dev, 0, sizeof(struct android_gpio_device_t));
	dev->common.tag = HARDWARE_DEVICE_TAG;
	dev->common.version = 0;
	dev->common.module = (hw_module_t*)module;
	dev->common.close = android_gpio_device_close;
	dev->set_val = android_gpio_set_val;
	dev->get_val = android_gpio_get_val;
	if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
		LOGE("android_gpio: failed to open /dev/AdrIO -- %s.", strerror(errno));
		free(dev);
		return -EFAULT;
	}
	*device = &(dev->common);
	return 0;
}  

static int android_gpio_device_close(struct hw_device_t* device)
{
	struct android_gpio_device_t* android_gpio_device = (struct android_gpio_device_t*)device;  

	if(android_gpio_device) {
	    close(android_gpio_device->fd);
	    free(android_gpio_device);
	}
	return 0;
}  

static int android_gpio_set_val(struct android_gpio_device_t* dev, int val)
{
	LOGI("android_gpio: set value %d to device.", val);
	write(dev->fd, &val, sizeof(val));
	return 0;
}  

static int android_gpio_get_val(struct android_gpio_device_t* dev, int* val)
{
	return 0;
}

为了防止调用时出现 Permission denied的情况:

打开system/core/rootdir目录,打开ueventd.rc添加:

/dev/android_gpio 0666 root root

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

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := android_gpio.c
LOCAL_MODULE := android_gpio.default
include $(BUILD_SHARED_LIBRARY)

编译HAL层:

mmm hardware/libhardware/modules/android_gpio

如果出现错误,参考:

No command ‘mmm‘ found

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

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

Install: out/target/product/generic/system/lib/hw/android_gpio.default.so

这个就是我们需要的硬件抽象层模块,这一步完成之后,还要接着向上走,最终完成硬件调用。

时间: 2024-10-29 10:46:14

Android 从硬件到应用:一步一步向上爬 3 -- 硬件抽象层访问硬件驱动的相关文章

Android 从硬件到应用:一步一步向上爬 6 -- 编写APP测试框架层硬件服务(完)

创建Android Application工程:使用Eclipse的Android插件ADT创建Android工程,工程名称为Gpio,创建完成后将工程目录拷贝到packages/apps/文件夹下,并删除工程目录下的gen文件夹,不删除的话会造成类重复的错误. src/com/android/gpio/Gpio.java: package com.android.gpio; import com.android.gpio.R; import android.app.Activity; impo

Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法调硬件驱动

Android下,java应用程序通过JNI方法调用硬件抽象层模块,在Android 从硬件到应用:一步一步向上爬 3 -- 硬件抽象层访问硬件驱动 中我们已经编译好了硬件抽象层模块,下面就要开始为HAL层编写JNI方法,为上层提供服务. cd到frameworks/base/services/jni目录中,新建一个com_android_server_GpioService.cpp文件: #include "jni.h" #include "JNIHelp.h"

Android 从硬件到应用:一步一步向上爬 1 -- 从零编写底层硬件驱动程序

硬件平台:TI AM335X Starter Kit 开发源码:TI-Android-ICS-4.0.3-DevKit-EVM-SK-3.0.1.bin 主机系统:Ubuntu 10.04 这次写<Android 从硬件到应用>是想尝试从底层的最简单的GPIO硬件驱动开始,一步一步的向上走,经过硬件抽象层HAL.JNI方法等,最终编写出APP,达到硬件调用的目的,期间会增加一些Android下C程序测试底层驱动的细节.既然是从零编写驱动,那就要脱离源码包里已有的一些api函数,从硬件电路开始.

Android 从硬件到应用:一步一步向上爬 5 -- 在Frameworks层添硬件服务

Android Frameworks层提供了硬件服务,Android系统APP可以调用这些硬件服务,进而完成硬件的控制,实现应有的功能.接着上一篇,这一篇要在frameworks层为应用提供java接口的硬件服务.cd到frameworks/base/core/java/android/os目录,添加 IGpioService.aidl: package android.os; interface IGpioService { void setVal(int val); int getVal()

Android教程-从零开始一步一步接入SDK

从零开始一步一步接入SDK 本篇博客想总结一下笔者在接入手游渠道SDK的一些经验方法,为想接入手游渠道或者想学习如何接入SDK的童鞋们提供一个参考.本篇博客基于Android平台,关于IOS接入SDK的方法,笔者以后有机会也会整理. 首先来给大家说明一下SDK,何为SDK?它的全称是,SoftWare Develop Kit,意思是软件开发工具包,它是可以辅助我们去开发某类软件的相关文档,范例和工具的集合.关于SDK,这里推荐一个服务商店,名叫Devstore(http://www.devsto

一步一步教你在 Android 里创建自己的账号系统(一)

大家如果喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 大家在平时使用 Android 手机的时候,都会发现有些应用(例如 qq,微信,淘宝)为自己创建了账号系统,并且能够在设置页面看到他,可是当自己希望为自己的软件写一个账号系统的时候总是不知从何入手,现在我们就从头开始,一步一步打造属于自己应用的账号系统. 在进行设备账户管理的时候,我们会通过一个 Acco

Ace教你一步一步做Android新闻客户端(一)

复制粘贴了那么多博文很不好意思没点自己原创的也说不出去,现在写一篇一步一步教你做安卓新闻客户端,借此机会也是让自己把相关的技术再复习一遍,大神莫笑,专门做给新手看. 手里存了两篇,一个包括软件视图 和新手引导 软件侧滑菜单 滑动主页的GUI篇 一个内容解析篇. 代码里有很详细的注释 所以直接放代码了 有不会的站内信或者评论我会及时回复. MainActivity XML :只有一个ListView布局 <?xml version="1.0" encoding="utf-

在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口(老罗学习笔记4)

在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为Android的Application Frameworks层提供硬件服务.我们知道,Android系统的应用程序是用Java语言编写的,而硬件驱动程序是用C语言来实现的,那么,Java接口如何去访问C接口呢?众所周知,Java提供了JNI方法调用,同样,在Android系统中,Java应用程序通过

android一步一步实现视频clientapp(一)

我开发完毕了一个完整的视频clientapp.如今.分享出来.供刚開始学习的人学习參考(大神就不用看了,比較简单,仅供入门),大家相互交流相互学习. 项目有些功能,我时间也不是非常多.仅仅能时不时更新下. 仅仅能大概解说怎么一步一步实现,相关的知识点.大家自己查阅相关文档了,本人非常多地方也是会使用,要我说出个详细的原理什么的,确实说不清,还有本人表达能力有限.大家仅仅能将就看看,不喜忽喷,哈哈. 还有为大家说下,怎么增加广告平台的广告,公布市场,获取收入(老实说本人app,加广告.基本没收入)