SPI模块的JNI方法提供Java访问HAL层服务接口

1、在frameworks/base/services/jni下创建spijni文件夹。

2、在spijni目录下创建com_android_server_SpiService.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 ...\n");
		array = env->GetByteArrayElements(jread_arr, NULL);
		if(array == NULL)
		{
			ALOGE("JniSpiRead: getByteArrayElements error!\n");
			return -1;
		}
		buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
		if(buf == NULL)
		{
			ALOGE("JniSpiRead: calloc error!\n");
			return -1;
		}
		
		spi_device->spi_read(spi_device, buf, len);
		for(i = 0; i < len; i++)
		{
			ALOGE("Spi Jni Read: data : %#x\n",*(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 ...\n");
		array = env->GetByteArrayElements(jwrite_arr, NULL);
		if(array == NULL)
		{
			ALOGE("JniSpiWrite: getByteArrayElements error!\n");
			return -1;
		}
		buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
		if(buf == NULL)
		{
			ALOGE("JniSpiWrite: calloc error!\n");
			return -1;
		}
		for(i = 0; i < len; i++)
		{
			*(buf + i) = (jboolean)(*(array + i));
			ALOGE("Spi Jni Write: data : %#x\n",*(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 ...\n");
		if(hw_get_module(SPI_HARDWARE_MODULE_ID, (const struct hw_module_t **)&Jspi_module) == 0)
		{
			ALOGE("Spi JNI: spi stub found.\n");
			if(spi_jni_open(&(Jspi_module->common), &spi_device) == 0)
			{
				ALOGE("Spi JNI: spi device is open.\n");
				if(spi_device)
				{
					spi_device->spi_init(spi_device);
					ALOGE("Spi JNI: spi init successfuly!\n");
					return true;
				}
				ALOGE("Spi JNI: spi init failed.\n");
				return false;
			}
			ALOGE("Spi JNI: failed to open spi device.\n");
			return false;
		}
		ALOGE("Spi JNI: failed to get spi stub module.\n");
		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\n",kClassName);
			return -1;
		}
		if(env->RegisterNatives(clazz,method_table, sizeof(method_table)/sizeof(method_table[0])) != JNI_OK)
		{
			ALOGE("Failed registering methods for %s\n",kClassName);
			return -1;
		}
		return 0;
	}
	extern "C" 
	
	jint JNI_OnLoad(JavaVM *vm, void *reserved)
	{
		JNIEnv *env = NULL;
		jint result = -1;
		ALOGE("Jni OnLoad ...\n");
		if(vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK)
		{
			ALOGE("ERROR: GetEnv failed .\n");
			goto fail;
		}
		assert(env != NULL);
		if(registerMethods(env) != 0)
		{
			ALOGE("ERROR: PlatformLibrary native registeration failed .\n");
			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目录下

     加执行权限 chown  root  libspi_servers.so

     chmod  777   libspi_servers.so

 

注意:如果无法打开设备节点/dev/spi1.0则

          加执行权限   chown  root  spi1.0

                             chmod  777   spi1.0

        无法加执行权限时执行:mount -o rw,remount -t ext4 /dev/block/mmcblk0p5 /system

                                                      chmod   777  /system


 

你可能感兴趣的:(java,android,linux,jni,ARM)