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"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/android_gpio.h>
#include <stdio.h>
namespace android
{
	struct android_gpio_device_t* android_gpio_device = NULL;  

	static void android_gpio_setVal(JNIEnv* env, jobject clazz, jint value)
	{
		int val = value;
		android_gpio_device->set_val(android_gpio_device, val);
	}  

	static jint android_gpio_getVal(JNIEnv* env, jobject clazz)
	{
		return 0;
	}  

	static inline int android_gpio_device_open(const hw_module_t* module, struct android_gpio_device_t** device)
	{
		return module->methods->open(module, ANDROID_GPIO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
	}  

	static jboolean android_gpio_init(JNIEnv* env, jclass clazz)
	{
		android_gpio_module_t* module;
		if(hw_get_module(ANDROID_GPIO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0)
		{
			if(android_gpio_device_open(&(module->common), &android_gpio_device) == 0)
			{
				return 0;
			}
			return -1;
	    	}
		return -1;
	}  

	static const JNINativeMethod method_table[] =
	{
		{"init_native", "()Z", (void*)android_gpio_init},
		{"setVal_native", "(I)V", (void*)android_gpio_setVal},
		{"getVal_native", "()I", (void*)android_gpio_getVal},
	};  

	int register_android_server_GpioService(JNIEnv *env) {
		return jniRegisterNativeMethods(env, "com/android/server/GpioService", method_table, NELEM(method_table));
	}
};  

其中ANDROID_GPIO_HARDWARE_MODULE_ID是在hardware/android_gpio.h中定义的,初始化时通过hw_get_module方法加载硬件层模块。 修改当前目录下的onload.cpp:

在namespace android中加入函数声明:

int register_android_server_GpioService(JNIEnv* env);

在JNI_Onload中加入函数调用:

register_android_server_GpioService(env);

修改frameworks/base/core/jni下的AndroidRuntime.cpp,在namespace android中加入声明:

extern int register_android_server_GpioService(JNIEnv* env);

修改当前目录下的Android.mk文件:

在LOCAL_SRC_FILES加入:

com_android_server_GpioService.cpp \

编译JNI方法:

mmm frameworks/base/services/jni

如果提示缺少libandroid_runtime.so、libsystem_server.so、libandroid_servers.so,执行:

make libandroid_runtime
make libsystem_server
make libandroid_servers

JNI方法编译完成后,就可以通过android硬件服务GpioService来调用JNI方法,以此来调用硬件抽象层访问底层硬件。

时间: 2024-12-25 01:02:27

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

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 从硬件到应用:一步一步向上爬 2 -- 运行 C 程序测试硬件驱动

编写C程序快速测试硬件驱动: 在Android 源码根目录下的external文件夹创建driver_test文件夹: cd external mkdir driver_test cd driver_test 创建Android.mk: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := driver_test LOCAL_SRC_FILES := dri

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 从硬件到应用:一步一步向上爬 3 -- 硬件抽象层访问硬件驱动

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

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教程-从零开始一步一步接入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应用程序通过