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