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/gpio.h>
#include <stdio.h>
namespace android
{
struct gpio_device_t* gpio_device = NULL; static void gpio_setVal(JNIEnv* env, jobject clazz, jint value)
{
int val = value;
gpio_device->set_val(gpio_device, val);
} static jint gpio_getVal(JNIEnv* env, jobject clazz)
{
return 0;
} static inline int gpio_device_open(const hw_module_t* module, struct gpio_device_t** device)
{
return module->methods->open(module, GPIO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
} static jboolean gpio_init(JNIEnv* env, jclass clazz)
{
gpio_module_t* module;
if(hw_get_module(GPIO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0)
{
if(gpio_device_open(&(module->common), &gpio_device) == 0)
{
return 0;
}
return -1;
}
return -1;
} static const JNINativeMethod method_table[] =
{
{"init_native", "()Z", (void*)gpio_init},
{"setVal_native", "(I)V", (void*)gpio_setVal},
{"getVal_native", "()I", (void*)gpio_getVal},
}; int register_android_server_GpioService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/GpioService", method_table, NELEM(method_table));
}
};
当中GPIO_HARDWARE_MODULE_ID是在hardware/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);
改动services/jni文件夹下的Android.mk文件:
在LOCAL_SRC_FILES增加:
com_android_server_GpioService.cpp \
编译JNI方法:
make TARGET_PRODUCT=am335xevm_sk -j8 OMAPES=4.x
假设成功,则生成libandroid_servers.so
out/target/product/am335xevm_sk/obj/lib/libandroid_servers.so
JNI方法编译完毕后,就能够通过android硬件服务GpioService来调用JNI方法,以此来调用硬件抽象层訪问底层硬件。
Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法调硬件驱动的更多相关文章
- Android 从硬件到应用程序:一步一步爬上去 6 -- 我写的APP测试框架层硬件服务(终点)
创Android Applicationproject:采用Eclipse的Android插入ADT创Androidproject,project名字Gpio,创建完成后,project文件夹pack ...
- 一步一步了解Cocos2dx 3.0 正式版本开发环境搭建(Win32/Android)
cocos2d-x 3.0发布有一段时间了,作为一个初学者,我一直觉得cocos2d-x很坑.每个比较大的版本变动,都会有不一样的项目创建方式,每次的跨度都挺大…… 但是凭心而论,3.0RC版本开始 ...
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口(老罗学习笔记4)
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...
- 一步一步学android控件(之十五) —— DegitalClock & AnalogClock
原本计划DigitalClock和AnalogClock单独各一篇来写,但是想想,两个控件的作用都一样,就和在一起写一篇了. DegitalClock和AnalogClock控件主要用于显示当前时间信 ...
- 一步一步学android控件(之十六)—— CheckBox
根据使用场景不同,有时候使用系统默认的CheckBox样式就可以了,但是有时候就需要自定义CheckBox的样式.今天主要学习如何自定义CheckBox样式.在CheckBox状态改变时有时需要做一些 ...
- 为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接 口.实现这两者的目的是为了向更上一层提供硬件访问接口,即 ...
- 一步一步学android控件(之六) —— MultiAutoCompleteTextView
今天学习的控件是MultiAutoCompleteTextView . 提到MultiAutoCompleteTextView 我们就自然而然地想到AutoCompleteTextView ,就想知道 ...
- Ace教你一步一步做Android新闻客户端(一)
复制粘贴了那么多博文很不好意思没点自己原创的也说不出去,现在写一篇一步一步教你做安卓新闻客户端,借此机会也是让自己把相关的技术再复习一遍,大神莫笑,专门做给新手看. 手里存了两篇,一个包括软件视图 和 ...
- android一步一步实现视频clientapp(一)
我开发完毕了一个完整的视频clientapp.如今.分享出来.供刚開始学习的人学习參考(大神就不用看了,比較简单,仅供入门),大家相互交流相互学习. 项目有些功能,我时间也不是非常多.仅仅能时不时更新 ...
随机推荐
- [Python] List & Object spread in Python
def myfunc(x, y, z): print(x, y, z) tuple_vec = (, , ) dict_vec = {, , } >>> myfunc(*tuple_ ...
- 71.sscanf数据挖掘
数据挖掘 sscanf(str, "%d %s %s %d %d %s %s %s", &ph[i].id, ph[i].name, ph[i].sex, &ph[ ...
- POJ3622 Gourmet Grazers(FHQ Treap)
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 2363 Accepted: 881 Description Like s ...
- Cisco安全防护读书笔记之一Cisco系统设备协议漏洞
650) this.width=650;" onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" ...
- 【agc009b】Tournament
Description 一场锦标赛有n个人,总共举办n-1次比赛,每次比赛必定一赢一输,输者不能再参赛.也就是整个锦标赛呈一个二叉树形式.已知一号选手是最后的胜者,以及对于i号选手(i>1)都知 ...
- 关于使用toFixed()函数时报错"toFixed() is not a function"的问题
toFixed()函数只有数字类型的参数才可使用,字符串类型的参数需用parseFloat或者parseInt转换后再使用
- BZOJ2329: [HNOI2011]括号修复(Splay)
解题思路: Replace.Swap.Invert都可以使用Splay完美解决(只需要解决一下标记冲突就好了). 最后只需要统计左右括号冲突就好了. 相当于动态统计最大前缀合和最小后缀和. 因为支持翻 ...
- 洛谷——P1443 马的遍历
https://www.luogu.org/problem/show?pid=1443#sub 题目描述 有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达 ...
- POJ--1753--Flip Game【DFS】
链接:http://poj.org/problem? id=1753 题意:一个4*4的方格,有白棋或者黑棋.每次操作是一个位置的颜色翻转,即白变黑.黑变白,而且与它相邻的四个位置的颜色也都跟着改变, ...
- 《从零開始学Swift》学习笔记(Day 59)——代码排版
原创文章,欢迎转载.转载请注明:关东升的博客 代码排版包括: 空行.空格.断行和缩进等内容.代码排版内容比較多工作量非常多.可是非常重要. 空行 空行将逻辑相关的代码段分隔开.以提高可读性. 下列情况 ...