SPIモジュールのJNIメソッドはJavaアクセスHAL層サービスインタフェースを提供する


1、frameworks/base/services/jniの下にspijniフォルダを作成します.
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