SPIモジュールのJNIメソッドはJavaアクセスHAL層サービスインタフェースを提供する
1、frameworks/base/services/jniの下にspijniフォルダを作成します.
2、spijniディレクトリの下でcom_を作成するandroid_server_SpiServices.cppとAndroid.mk.
com_android_server_SpiService.cpp
Android.mk
3、ソースマスターディレクトリの下で実行コマンドをコンパイルする:mmm frameworks/base/services/jni.
4、生成ライブラリのパスout/target/product/sabresd_6dq/symbols/system/lib/libspi_servers.so.
5、生成したライブラリを開発ボードの/system/libディレクトリの下に置く
実行権限を付与 root libspi_servers.so
chmod 777 libspi_servers.so
注:デバイスノード/dev/spi 1.0を開くことができない場合は
実行権限の追加 chown root spi1.0
chmod 777 spi1.0
実行権限を付与できない場合実行:mount-o rw,remount-t ext 4/dev/block/mmcblk 0 p 5/system
chmod 777 /system
2、spijniディレクトリの下でcom_を作成するandroid_server_SpiServices.cppとAndroid.mk.
com_android_server_SpiService.cpp
#define LOG_TAG "SpiService"
#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/spihal.h>
#include <stdio.h>
#include <fcntl.h>
namespace android
{
/* HAL */
struct spi_device_t *spi_device = NULL;
/* spi */
static jint spi_jni_read(JNIEnv *env, jobject clazz, jbyteArray jread_arr, jint len)
{
jbyte *array = NULL;
jboolean *buf;
int i = 0;
ALOGE("Jni Spi Read ...
");
array = env->GetByteArrayElements(jread_arr, NULL);
if(array == NULL)
{
ALOGE("JniSpiRead: getByteArrayElements error!
");
return -1;
}
buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
if(buf == NULL)
{
ALOGE("JniSpiRead: calloc error!
");
return -1;
}
spi_device->spi_read(spi_device, buf, len);
for(i = 0; i < len; i++)
{
ALOGE("Spi Jni Read: data : %#x
",*(buf + i));
*(array + i) = (jchar)(*(buf + i));
}
env->ReleaseByteArrayElements(jread_arr, array, 0);
free(buf);
buf = NULL;
return 0;
}
/* spi */
static jint spi_jni_write(JNIEnv *env, jobject clazz, jbyteArray jwrite_arr, jint len)
{
jbyte *array = NULL;
jboolean *buf;
int i = 0;
ALOGE("Jni Spi Write ...
");
array = env->GetByteArrayElements(jwrite_arr, NULL);
if(array == NULL)
{
ALOGE("JniSpiWrite: getByteArrayElements error!
");
return -1;
}
buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
if(buf == NULL)
{
ALOGE("JniSpiWrite: calloc error!
");
return -1;
}
for(i = 0; i < len; i++)
{
*(buf + i) = (jboolean)(*(array + i));
ALOGE("Spi Jni Write: data : %#x
",*(buf + i));
}
env->ReleaseByteArrayElements(jwrite_arr, array, 0);
spi_device->spi_write(spi_device, buf, len);
free(buf);
buf = NULL;
return 0;
}
/* spi */
static inline int spi_jni_open(const hw_module_t * module, struct spi_device_t **device)
{
return module->methods->open(module, SPI_HARDWARE_MODULE_ID, (struct hw_device_t **)device);
}
/* spi */
static jboolean spi_jni_init(JNIEnv *env, jclass clazz)
{
spi_module_t *Jspi_module;
ALOGE("Spi JNI: spi initializing ...
");
if(hw_get_module(SPI_HARDWARE_MODULE_ID, (const struct hw_module_t **)&Jspi_module) == 0)
{
ALOGE("Spi JNI: spi stub found.
");
if(spi_jni_open(&(Jspi_module->common), &spi_device) == 0)
{
ALOGE("Spi JNI: spi device is open.
");
if(spi_device)
{
spi_device->spi_init(spi_device);
ALOGE("Spi JNI: spi init successfuly!
");
return true;
}
ALOGE("Spi JNI: spi init failed.
");
return false;
}
ALOGE("Spi JNI: failed to open spi device.
");
return false;
}
ALOGE("Spi JNI: failed to get spi stub module.
");
return false;
}
/* JNI */
static const JNINativeMethod method_table[] =
{
{"native_init", "()Z", (void *)spi_jni_init},
{"native_write", "([BI)I", (void *)spi_jni_write},
{"native_read", "([BI)I", (void *)spi_jni_read},
};
/* JNI */
static int registerMethods(JNIEnv *env)
{
static const char *const kClassName = "com/android/server/SpiService";
jclass clazz;
clazz = env->FindClass(kClassName);
if(clazz == NULL)
{
ALOGE("Can't find class %s
",kClassName);
return -1;
}
if(env->RegisterNatives(clazz,method_table, sizeof(method_table)/sizeof(method_table[0])) != JNI_OK)
{
ALOGE("Failed registering methods for %s
",kClassName);
return -1;
}
return 0;
}
extern "C"
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env = NULL;
jint result = -1;
ALOGE("Jni OnLoad ...
");
if(vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK)
{
ALOGE("ERROR: GetEnv failed .
");
goto fail;
}
assert(env != NULL);
if(registerMethods(env) != 0)
{
ALOGE("ERROR: PlatformLibrary native registeration failed .
");
goto fail;
}
result = JNI_VERSION_1_4;
fail:
return result;
}
};
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
com_android_server_SpiService.cpp \
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
frameworks/base/services \
frameworks/base/core/jni \
external/skia/include/core \
libcore/include \
libcore/include/libsuspend \
$(call include-path-for, libhardware)/hardware \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libandroidfw \
libcutils \
liblog \
libhardware \
libhardware_legacy \
libnativehelper \
libsystem_server \
libutils \
libui \
libinput \
libskia \
libgui \
libusbhost \
libsuspend
ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
endif
LOCAL_MODULE:= libspi_servers
include $(BUILD_SHARED_LIBRARY)
3、ソースマスターディレクトリの下で実行コマンドをコンパイルする:mmm frameworks/base/services/jni.
4、生成ライブラリのパスout/target/product/sabresd_6dq/symbols/system/lib/libspi_servers.so.
5、生成したライブラリを開発ボードの/system/libディレクトリの下に置く
実行権限を付与 root libspi_servers.so
chmod 777 libspi_servers.so
注:デバイスノード/dev/spi 1.0を開くことができない場合は
実行権限の追加 chown root spi1.0
chmod 777 spi1.0
実行権限を付与できない場合実行:mount-o rw,remount-t ext 4/dev/block/mmcblk 0 p 5/system
chmod 777 /system