【转】Android 驱动开发系列四
原文网址:http://www.2cto.com/kf/201304/202040.html
时隔多日,终于都抽出时间来写blog了。废话不多说,接着上一篇,这里将介绍如何编写HAL层(硬件抽象层)对应的JNI方法。
这里提到的都是在ICS源码里编译的。
1、定义JNI层接口
进入到android-4.0.4_r1.2/hardware/libhardware/include/hardware目录,并创建 ttt.h 文件,内容如下:
[cpp]
#ifndef ANDROID_TTT_INTERFACE_H
#define ANDROID_TTT_INTERFACE_H
#include <hardware/hardware.h>
__BEGIN_DECLS
// 定义模块ID
#define HELLO_HARDWARE_MODULE_ID "ttt"
// 硬件模块结构体
struct ttt_module_t{
struct hw_module_t common;
};
// hardware interface struct
struct ttt_device_t{
struct hw_device_t common;
int fd;
int(*set_val)(struct ttt_device_t* dev, int val);
int(*get_val)(struct ttt_device_t* dev, int* val);
};
__END_DECLS
#endif
#ifndef ANDROID_TTT_INTERFACE_H
#define ANDROID_TTT_INTERFACE_H
#include <hardware/hardware.h>
__BEGIN_DECLS
// 定义模块ID
#define HELLO_HARDWARE_MODULE_ID "ttt"
// 硬件模块结构体
struct ttt_module_t{
struct hw_module_t common;
};
// hardware interface struct
struct ttt_device_t{
struct hw_device_t common;
int fd;
int(*set_val)(struct ttt_device_t* dev, int val);
int(*get_val)(struct ttt_device_t* dev, int* val);
};
__END_DECLS
#endif
2、实现JNI层接口功能
进入到android-4.0.4_r1.2/frameworks/base/services/jni目录,并创建com_android_server_TTTService.cpp文件,其内容如下:
[cpp]
#define LOG_TAG "TTTService"
#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/ttt.h>
#include <stdio.h>
namespace android
{
struct ttt_device_t* ttt_device = NULL;
// through the HAL interface to set the register value
static void ttt_setVal(JNIEnv* env, jobject clazz, jint value){
int val = value;
LOGI("TTT JNI: set value %d to device.", val);
if(!ttt_device){
LOGI("TTT JNI: device is not open.");
return;
}
ttt_device->set_val(ttt_device, val);
}
// through the HAL interface to read the register value
static jint ttt_getVal(JNIEnv* env, jobject clazz){
int val = 0;
if(!ttt_device){
LOGI("TTT JNI: device is not open.");
return val;
}
ttt_device->get_val(ttt_device, &val);
LOGI("TTT JNI: get value %d from device.", val);
return val;
}
// through the HAL interface to open the hardware device
static inline int ttt_device_open(const hw_module_t* module, struct ttt_device_t** device){
return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
}
// throught the hardware module ID to load the HAL module and open the device
static jboolean ttt_init(JNIEnv* env, jclass clazz){
ttt_module_t* module;
LOGI("TTT JNI: initializing...");
if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0){
LOGI("TTT JNI: ttt stub found.");
if(ttt_device_open(&(module->common), &ttt_device) == 0){
LOGI("TTT JNI: ttt device is open.");
return 0;
}
LOGE("TTT JNI: failed to open ttt device.");
return -1;
}
LOGE("TTT JNI: failed to get ttt stub module.");
return -1;
}
// JNI methods table
static const JNINativeMethod method_table[] = {
{"init_native", "()Z", (void*)ttt_init},
{"setVal_native", "(I)V", (void*)ttt_setVal},
{"getVal_native", "()I", (void*)ttt_getVal},
};
// regist JNI method
int register_android_server_TTTService(JNIEnv* env){
return jniRegisterNativeMethods(env, "com/android/server/TTTService", method_table, NELEM(method_table));
}
};
#define LOG_TAG "TTTService"
#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/ttt.h>
#include <stdio.h>
namespace android
{
struct ttt_device_t* ttt_device = NULL;
// through the HAL interface to set the register value
static void ttt_setVal(JNIEnv* env, jobject clazz, jint value){
int val = value;
LOGI("TTT JNI: set value %d to device.", val);
if(!ttt_device){
LOGI("TTT JNI: device is not open.");
return;
}
ttt_device->set_val(ttt_device, val);
}
// through the HAL interface to read the register value
static jint ttt_getVal(JNIEnv* env, jobject clazz){
int val = 0;
if(!ttt_device){
LOGI("TTT JNI: device is not open.");
return val;
}
ttt_device->get_val(ttt_device, &val);
LOGI("TTT JNI: get value %d from device.", val);
return val;
}
// through the HAL interface to open the hardware device
static inline int ttt_device_open(const hw_module_t* module, struct ttt_device_t** device){
return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
}
// throught the hardware module ID to load the HAL module and open the device
static jboolean ttt_init(JNIEnv* env, jclass clazz){
ttt_module_t* module;
LOGI("TTT JNI: initializing...");
if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0){
LOGI("TTT JNI: ttt stub found.");
if(ttt_device_open(&(module->common), &ttt_device) == 0){
LOGI("TTT JNI: ttt device is open.");
return 0;
}
LOGE("TTT JNI: failed to open ttt device.");
return -1;
}
LOGE("TTT JNI: failed to get ttt stub module.");
return -1;
}
// JNI methods table
static const JNINativeMethod method_table[] = {
{"init_native", "()Z", (void*)ttt_init},
{"setVal_native", "(I)V", (void*)ttt_setVal},
{"getVal_native", "()I", (void*)ttt_getVal},
};
// regist JNI method
int register_android_server_TTTService(JNIEnv* env){
return jniRegisterNativeMethods(env, "com/android/server/TTTService", method_table, NELEM(method_table));
}
};
3、添加JNI初始化调用
修改android-4.0.4_r1.2/frameworks/base/services/jni目录下的 onload.cpp 文件,在 JNI_OnLoad函数中的return之前添加下面一句:
[cpp]
register_android_server_TTTService(env);
register_android_server_TTTService(env);同时,在该文件中的namespace中添加下面一句声明:
[cpp]
int register_android_server_TTTService(JNIEnv* env);
int register_android_server_TTTService(JNIEnv* env);
这样,在系统初始化时,就会调用register_android_server_TTTService方法来加载JNI方法了。
4、添加编译JNI的配置
修改android-4.0.4_r1.2/frameworks/base/services/jni目录下的 Android.mk 文件,在 LOCAL_SRC_FILES 变量中添加下面一行:
[cpp]
com_android_server_TTTService.cpp \
com_android_server_TTTService.cpp \这里是添加编译配置。
5、开始编译
[cpp]
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# . build/envsetup.sh
including device/moto/stingray/vendorsetup.sh
including device/moto/wingray/vendorsetup.sh
including device/samsung/crespo4g/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
including device/samsung/maguro/vendorsetup.sh
including device/samsung/smdkc110/vendorsetup.sh
including device/samsung/smdkv210/vendorsetup.sh
including device/samsung/torospr/vendorsetup.sh
including device/samsung/toro/vendorsetup.sh
including device/samsung/tuna/vendorsetup.sh
including device/ti/panda/vendorsetup.sh
including sdk/bash_completion/adb.bash
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# . build/envsetup.sh
including device/moto/stingray/vendorsetup.sh
including device/moto/wingray/vendorsetup.sh
including device/samsung/crespo4g/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
including device/samsung/maguro/vendorsetup.sh
including device/samsung/smdkc110/vendorsetup.sh
including device/samsung/smdkv210/vendorsetup.sh
including device/samsung/torospr/vendorsetup.sh
including device/samsung/toro/vendorsetup.sh
including device/samsung/tuna/vendorsetup.sh
including device/ti/panda/vendorsetup.sh
including sdk/bash_completion/adb.bash
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#[cpp] view plaincopyprint?root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm frameworks/base/services/jni
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.4
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IMM76I
============================================
make:进入目录'/home/brantyou/workspace/android-4.0.4_r1.2'
target thumb C++: libandroid_servers <= frameworks/base/services/jni/com_android_server_HelloService.cpp
target thumb C++: libandroid_servers <= frameworks/base/services/jni/com_android_server_TTTService.cpp
target thumb C++: libandroid_servers <= frameworks/base/services/jni/onload.cpp
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so”需要的目标“out/target/product/generic/obj/lib/libsystem_server.so”。 停止。
make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm frameworks/base/services/jni
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.4
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IMM76I
============================================
make:进入目录'/home/brantyou/workspace/android-4.0.4_r1.2'
target thumb C++: libandroid_servers <= frameworks/base/services/jni/com_android_server_HelloService.cpp
target thumb C++: libandroid_servers <= frameworks/base/services/jni/com_android_server_TTTService.cpp
target thumb C++: libandroid_servers <= frameworks/base/services/jni/onload.cpp
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so”需要的目标“out/target/product/generic/obj/lib/libsystem_server.so”。 停止。
make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#
矮油~~~这里出错了,提示没有找到 libsystem_server.so 文件。
执行下面的命令,生成 libsystem_server.so 文件:
[cpp]
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make libsystem_server
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make libsystem_server生成之后的提示:
[cpp]
Install: out/target/product/generic/system/lib/libvorbisidec.so
Install: out/target/product/generic/system/lib/libstagefright_yuv.so
Install: out/target/product/generic/system/lib/libdrmframework.so
Install: out/target/product/generic/system/lib/libchromium_net.so
Install: out/target/product/generic/system/lib/libstagefright_amrnb_common.so
Install: out/target/product/generic/system/lib/libstagefright_enc_common.so
Install: out/target/product/generic/system/lib/libstagefright_avc_common.so
Install: out/target/product/generic/system/lib/libstagefright.so
Install: out/target/product/generic/system/lib/libstagefright_omx.so
Install: out/target/product/generic/system/lib/libmediaplayerservice.so
Install: out/target/product/generic/system/lib/libinput.so
Install: out/target/product/generic/system/lib/libsystem_server.so
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#
Install: out/target/product/generic/system/lib/libvorbisidec.so
Install: out/target/product/generic/system/lib/libstagefright_yuv.so
Install: out/target/product/generic/system/lib/libdrmframework.so
Install: out/target/product/generic/system/lib/libchromium_net.so
Install: out/target/product/generic/system/lib/libstagefright_amrnb_common.so
Install: out/target/product/generic/system/lib/libstagefright_enc_common.so
Install: out/target/product/generic/system/lib/libstagefright_avc_common.so
Install: out/target/product/generic/system/lib/libstagefright.so
Install: out/target/product/generic/system/lib/libstagefright_omx.so
Install: out/target/product/generic/system/lib/libmediaplayerservice.so
Install: out/target/product/generic/system/lib/libinput.so
Install: out/target/product/generic/system/lib/libsystem_server.so
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# 好了,这个问题解决了,我们继续编译这个JNI。
[cpp]
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm frameworks/base/services/jni
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.4
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IMM76I
============================================
make:进入目录'/home/brantyou/workspace/android-4.0.4_r1.2'
target SharedLib: libandroid_servers (out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so)
target Symbolic: libandroid_servers (out/target/product/generic/symbols/system/lib/libandroid_servers.so)
target Strip: libandroid_servers (out/target/product/generic/obj/lib/libandroid_servers.so)
Install: out/target/product/generic/system/lib/libandroid_servers.so
make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# mmm frameworks/base/services/jni
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.4
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IMM76I
============================================
make:进入目录'/home/brantyou/workspace/android-4.0.4_r1.2'
target SharedLib: libandroid_servers (out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so)
target Symbolic: libandroid_servers (out/target/product/generic/symbols/system/lib/libandroid_servers.so)
target Strip: libandroid_servers (out/target/product/generic/obj/lib/libandroid_servers.so)
Install: out/target/product/generic/system/lib/libandroid_servers.so
make:离开目录“/home/brantyou/workspace/android-4.0.4_r1.2”
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#很好,这一次已经顺利的编译完了。
下面我们需要重新打包这个 system.img,包我们编写的JNI方法包含进去:
[cpp]
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make snod
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.4
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IMM76I
============================================
make snod: ignoring dependencies
Target system fs image: out/target/product/generic/system.img
out/target/product/generic/system.img total size is 44107008
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2#
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make snod
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.4
TARGET_PRODUCT=full
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IMM76I
============================================
make snod: ignoring dependencies
Target system fs image: out/target/product/generic/system.img
out/target/product/generic/system.img total size is 44107008
root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# 这样就成功的把我们编写的JNI打包到 system.img中了。
【转】Android 驱动开发系列四的更多相关文章
- 初入android驱动开发之字符设备(四-中断)
上一篇讲到android驱动开发中,应用是怎样去操作底层硬件的整个流程,实现了按键控制led的亮灭.当然,这是一个非常easy的实例,只是略微演变一下,就能够得到广泛的应用. 如开发扫描头,应用透过监 ...
- Android商城开发系列(四)——butterknife的使用
在上一篇博客:Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏实现商城的底部导航栏时,里面用到了butterknife,今天来讲解一下的butterk ...
- S5PV210开发系列四_uCGUI的移植
S5PV210开发系列四 uCGUI的移植 象棋小子 1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...
- Android驱动开发5-8章读书笔记
Android驱动开发读书笔记 第五章 S5PV210是一款32位处理器,具有 ...
- Android驱动开发前的准备
最近看了一些Android驱动开发前需要知道的资料,收获很多,接下来就谈谈我自己的一些心得体会. Android在近几年时间发展迅速,已经成为智能手机操作系统的老大.不过,因为Android原生的代码 ...
- Android 快速开发系列 打造万能的ListView GridView 适配器
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...
- Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能
Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...
- Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片
Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一 ...
- 转:arcgis api for js入门开发系列四地图查询
原文地址:arcgis api for js入门开发系列四地图查询 arcgis for js的地图查询方式,一般来说,总共有三种查询方式:FindTask.IdentifyTask.QueryTas ...
随机推荐
- python np.linspace
该函数的形式为: linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) 作用为:在规定的时间内,返回固定间隔的 ...
- css制作导航栏的上下三角
1)先完成一个导航条 <style type="text/css"> .nav-ul{ list-style: none; } .nav-ul li{ width: 1 ...
- C#一般处理程序获取Session
如果需要用ajax去动态校验验证码,如何获取Session保存的值呢? 你需要做两步: 一.在你的一般处理程序中添加命名空间 (using System.Web.SessionState;) 二.在你 ...
- query 防止ajax重复提交
项目用到js了,首选jquery,能用库用库,原则. 碰到重复提交的问题,禁止住才行.百度google,还是Google给力. 知乎上有个高人,总结了四种,利用Jquery .post方法返回jqXH ...
- SQL通过传递参数方式备份数据库.
存储过程的SQL代码: ALTER PROCEDURE USP_DBBackup ), --存储目录. ) --存储数据库名. AS SET NOCOUNT ON ) select @name = r ...
- 关于wordpress中更换CKEditor编辑器
wordpress中自带的编辑器实在是功能太简,连插入表格都没有,使用插件的方式太过于麻烦,干脆就直接更换编辑器了,在网上找了一些方法,下文引自http://down.chinaz.com/try/2 ...
- Windows7 QT5.6.0(64位)使用mysql(64位)环境搭建详解
1 说明 使用环境为:Windows7 VS2015 QT5.6.0(64位),MYSQL 5.7.13(64位). 网上各种错误.模糊.抽象的资料,配置环境花了半天,痛定思痛,总结出来,方便后来人. ...
- 【感悟】看Hyouka的感想 (1)
最近偶然从B站看到了<冰菓>这个(个人觉得是推理)番 我突然觉得自己曾经做的一些行为欠妥 有才能者的不自知,是对无才能者的讽刺 举个例子就是:即当别人说你很牛的时候,你却说你只 ...
- 设计模式之 Singleton 单例模式
先上两段代码,区别仅在于是否涉及线程安全. 首先是不涉及多线程的单例: public class Singleton { private final static Singleton INSTANCE ...
- jquery live()只支持css选择器
昨天在处理过keypress键盘事件后,今天要把用户在页面上动态添加的字段条目加上删除功能,就是在每个字段后面加上一个漂亮的小按钮,当用户点击这个按钮,相应的条目就被从数据库中删除. 为了实现这种功能 ...