来自:http://blog.csdn.net/hanbo622/article/details/38944895
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