zoukankan      html  css  js  c++  java
  • [Andorid] 通过JNI实现kernel与app进行spi通讯

    CPU:RK3399

    系统:Android 7.1

    人脸识别的要求越来越高,因此主板增加了 SE 加密芯片,加密芯片通过 spi 接口与 CPU 通讯。

    对于 kernel 层的代码,Linux 原始代码中有很经典的参考驱动,可以仿照写 spi 驱动。

    如果没有过多要求,只需要修改设备号和节点名称,然后能和 dts 匹配成功就行,最后记得修改生成的节点权限

    path:kernel/drivers/spi/spidev.c

    diff --git a/device/rockchip/common/ueventd.rockchip.rc b/device/rockchip/common/ueventd.rockchip.rc
    index 8d5d28d..4b6ac2a 100644
    --- a/device/rockchip/common/ueventd.rockchip.rc
    +++ b/device/rockchip/common/ueventd.rockchip.rc
    @@ -65,6 +65,8 @@
     /dev/ttyS2                     0666   system     system
     /dev/ttyS3                     0666   system     system
     
    +/dev/thm36                     0666   system     system
    +
     # for radio
     /dev/ttyUSB0                   0660   radio      radio
     /dev/ttyUSB1                   0660   radio      radio

    JNI 的代码就需要自己完成(不需要 HAL 层),然后将 JNI 添加到 App 中编译。

    下面代码只是实现简单的读写功能,完成 app 和 kernel 之间的通讯,复杂的地方就是数组之间的转化。

    JNI 文件名:thm36_jni.c

    #include <jni.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <termios.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    
    #include "android/log.h"
    
    static const char *TAG = "thm36_jni";
    
    #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
    #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
    #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
    
    #define DEV_NAME    "/dev/thm36"
    
    static jint fd;
    
    JNIEXPORT jint JNICALL Java_com_example_aaron_se_Thm36Native_thm36Open(JNIEnv *env, jclass clazz)
    {
        LOGD("JNI spi open ... ...");
        
        fd = open(DEV_NAME, O_RDWR);
        if (fd < 0)
        {
            LOGD("open device fail!");
            return -1;
        }
        
        return 0;
    }
    
    JNIEXPORT void JNICALL Java_com_example_aaron_se_Thm36Native_thm36Close(JNIEnv *env, jclass clazz)
    {
        LOGD("JNI spi close ... ...");
        
        close(fd);
    }
    
    JNIEXPORT jint JNICALL Java_com_example_aaron_se_Thm36Native_thm36Read(JNIEnv *env, jclass clazz, jbyteArray jread_arr, jint len)
    {
        jbyte *array = NULL;
        jboolean *buf;
        int  i = 0;
        
        LOGD("JNI spi read ... ...");
        
        array = (*env)->GetByteArrayElements(env, jread_arr, NULL);
        if (array == NULL)
        {
            LOGD("JNI spi read: GetByteArrayElements faid!");
            return -1;
        }
        
        buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
        if (buf == NULL)
        {
            LOGD("JNI spi read: calloc fail!");
            return -1;
        }
        
        read(fd, buf, len);
        for (i=0; i<len; i++)
        {
            LOGD("JNI spi read: buf: %#x", *(buf + i));
            *(array + i) = (jchar)(*(buf + i));
        }
        
        (*env)->ReleaseByteArrayElements(env, jread_arr, array, 0);
        
        free(buf);
        
        return 0;
    }
    
    JNIEXPORT jint JNICALL Java_com_example_aaron_se_Thm36Native_thm36Write(JNIEnv *env, jclass clazz, jbyteArray jwrite_arr, jint len)
    {
        jbyte *array = NULL;
        jboolean *buf;
        int i = 0;
        
        LOGD("JNI spi write ... ...");
        
        array = (*env)->GetByteArrayElements(env, jwrite_arr, NULL);
        if (array == NULL)
        {
            LOGD("JNI spi write: GetByteArrayElements fail!");
            return -1;
        }
        
        buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
        if(buf == NULL)
        {
            LOGD("JNI spi write: calloc fail!");
            return -1;
        }
        
        for(i = 0; i < len; i++)
        {
            *(buf + i) = (jboolean)(*(array + i));
            LOGD("JNI spi write: data : %#x
    ",*(buf + i));
        }
        
        (*env)->ReleaseByteArrayElements(env, jwrite_arr, array, 0);
        
        write(fd, buf, len);
        
        free(buf);
        
        return 0;
    }

    编译文件:Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    TARGET_PLATFORM := android-3
    LOCAL_MODULE    := thm36_jni
    LOCAL_SRC_FILES := thm36_jni.c
    LOCAL_LDLIBS    := -llog
    
    include $(BUILD_SHARED_LIBRARY)

    App 的测试代码也很简单,一个是主活动,一个是与 JNI 链接

    MainActivity.java

    // JNI中的函数名前面部分要与此相同
    package com.example.aaron.se;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        Thm36Native thm36 = new Thm36Native();
        byte[] tx = {(byte)0xAA, 0x00, 0x06, 0x00, (byte)0xCA, 0x00, 0x00, 0x00, 0x00, (byte)0xCA};
        byte[] rx = new byte[22];
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button btn = (Button) findViewById(R.id.btn);
    
            btn.setOnClickListener(MainActivity.this);
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.btn:
                    thm36.thm36Open();
                    thm36.thm36Write(tx, tx.length);
                    thm36.thm36Read(rx, rx.length);
                    thm36.thm36Close();
                    break;
    
                default:
                    break;
            }
        }
    }

    Thm36Native.java

    package com.example.aaron.se;
    
    import android.util.Log;
    
    public class Thm36Native {
    
        private final String TAG = "Thm36Native";
    
        public native int thm36Open();
        public native void thm36Close();
        public native int thm36Read(byte[] buf, int len);
        public native int thm36Write(byte[] buf, int len);
    
        static {
            System.loadLibrary("thm36");
        }
    }

    参考:

    https://blog.csdn.net/hanbo622/article/details/38944895

  • 相关阅读:
    leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
    leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence
    leetcode64. Minimum Path Sum
    leetcode 20 括号匹配
    算法题待做
    leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown 、714. Best Time to Buy and Sell Stock with Transaction Fee
    rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
    依图
    leetcode 1.Two Sum 、167. Two Sum II
    从分类,排序,top-k多个方面对推荐算法稳定性的评价
  • 原文地址:https://www.cnblogs.com/lialong1st/p/11608989.html
Copyright © 2011-2022 走看看