您的位置:首页 > 移动开发 > Android开发

Android 驱动开发系列四

2016-04-19 17:11 465 查看
转至:http://blog.csdn.net/brantyou/article/details/8781017

时隔多日,终于都抽出时间来写blog了。废话不多说,接着上一篇,这里将介绍如何编写HAL层(硬件抽象层)对应的JNI方法。

这里提到的都是在ICS源码里编译的。

1、定义JNI层接口

进入到Android-4.0.4_r1.2/hardware/libhardware/include/hardware目录,并创建 ttt.h 文件,内容如下:

[cpp] view
plain copy

#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] view
plain copy

#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] view
plain copy

register_android_server_TTTService(env);

同时,在该文件中的namespace中添加下面一句声明:

[cpp] view
plain copy

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] view
plain copy

com_android_server_TTTService.cpp \

这里是添加编译配置。



5、开始编译

[cpp] view
plain copy

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
plain copy

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] view
plain copy

root@brantyou-ubuntu:~/workspace/android-4.0.4_r1.2# make libsystem_server

生成之后的提示:

[cpp] view
plain copy

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] view
plain copy

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] view
plain copy

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中了。

这章到此结束,下一章将介绍,如何基于JNI接口编写对应的服务和编写对应的Android程序来访问服务。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: