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 < )
{
LOGD("open device fail!");
return -;
} return ;
} 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 = ; LOGD("JNI spi read ... ..."); array = (*env)->GetByteArrayElements(env, jread_arr, NULL);
if (array == NULL)
{
LOGD("JNI spi read: GetByteArrayElements faid!");
return -;
} buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
if (buf == NULL)
{
LOGD("JNI spi read: calloc fail!");
return -;
} read(fd, buf, len);
for (i=; i<len; i++)
{
LOGD("JNI spi read: buf: %#x", *(buf + i));
*(array + i) = (jchar)(*(buf + i));
} (*env)->ReleaseByteArrayElements(env, jread_arr, array, ); free(buf); return ;
} 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 = ; LOGD("JNI spi write ... ..."); array = (*env)->GetByteArrayElements(env, jwrite_arr, NULL);
if (array == NULL)
{
LOGD("JNI spi write: GetByteArrayElements fail!");
return -;
} buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
if(buf == NULL)
{
LOGD("JNI spi write: calloc fail!");
return -;
} for(i = ; i < len; i++)
{
*(buf + i) = (jboolean)(*(array + i));
LOGD("JNI spi write: data : %#x\n",*(buf + i));
} (*env)->ReleaseByteArrayElements(env, jwrite_arr, array, ); write(fd, buf, len); free(buf); return ;
}

编译文件: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

[Andorid] 通过JNI实现kernel与app进行spi通讯的更多相关文章

  1. APP邂逅即时通讯云,让你的手机APP聊起来

     #推荐活动# #线下沙龙# 明天下午在IC咖啡 —— <APP邂逅即时通讯云,让你的手机APP聊起来>, http://url.cn/Y8sYo5 

  2. 7.app和app后端的通讯

    经常有开发者问:app和后端通讯是用http协议还是私有的协议?是用长连接还是短连接?通过阅读本文,帮你解除上面的疑问. (1)是用http协议还是私有的协议? 在间谍电视剧中,经常能看到间谍们的书信 ...

  3. Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块

    一直想写一份技术文档,但因为自感能力有限而无从下笔,近期做了个关于Android平台下实现与C语言的通讯来操作蓝牙模块的项目,中间碰到了很多问题,也在网上查了很多资料,在完毕主要功能后.也有一些人在网 ...

  4. 怎样将runlmbench 获取的数值传给上层app

    前面那个随笔 , 已经成功将runlmbench 移植到了Android , 并成功的运行. 今天就写一下将runlmbench 获取的那些性能值传给上层 App 进行人机交互. 一开始 , 我是想直 ...

  5. Co-Debugging JNI with Android Studio and Visual Studio

    Tutorials > Android > Integration with other tools > Co-Debugging JNI with Android Studio a ...

  6. React Native 4 for Android源码分析 一《JNI智能指针之介绍篇》

    文/ Tamic: http://blog.csdn.net/sk719887916/article/details/53455441 原文:http://blog.csdn.net/eewolf/a ...

  7. 超级简单的Android Studio jni 实现(无需命令行)【转载】

    原文: http://www.jianshu.com/p/e689d0196a17 1.配置Anroid Studio(这步是关键) 使用[command+,] 打开Preferences,选择Ext ...

  8. AndroidStudio 开发JNI

    Android版本不断更新,发现网上很多JNI的教程,都不太适用了,会遇到各种问题,今天自己来总结一个. NDK下载 我们下载NDK,有两种下载方式: 这是Google官方下载 点击下载NDK: 通过 ...

  9. App优化 Systrace

    简介 trace [tres] vt.跟踪,追踪; 追溯,探索; 探索; 查找; n.痕迹; 痕迹,踪迹; 微量,极少量; 1 1   1 trace [tres] vt.跟踪,追踪; 追溯,探索; ...

随机推荐

  1. OpenStack kilo版(3) Nova部署

    部署在controller和compute节点 配置数据库 MariaDB [(none)]> CREATE DATABASE nova;  Query OK, 1 row affected ( ...

  2. C#-NPOI操作EXCEL

    1.获取NUGET NPOI包. 2.引用命名空间 using NPOI.SS.UserModel;using NPOI.XSSF.UserModel;using NPOI.HSSF.UserMode ...

  3. Android笔记(二十九) Android中的异步更新(一) Android中的线程

    Java中的线程 1. 线程的两种实现方式 ①继承Thread类 ②实现Runnable接口 两者区别在于,Thread这个类的对象,代表的是一个线程,而Runnable的对象,代表的是线程体(也就是 ...

  4. CentOS7.X版本系统的下载和安装

    一.下载CentOS镜像 1.打开浏览器输入centos.org 2.选择版本下载 3.进入下载页面选择下载版本的种子链接,在迅雷下载即可. 二安装CentOS系统 1.服务器开机,根据界面提示进入磁 ...

  5. Win10安装MySQL5.7版本 解压缩版方法

    1.下载地址:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 直接点击下载项 下载后: 2.可以把解压的内容随便放到一个目录,我的是如 ...

  6. iptables详解(6):iptables扩展模块之 state 扩展

    为了防止恶意攻击主动连接到你的主机 我们需要通过iptables的扩展模块判断报文是为了回应我们之前发出的报文还是主动向我们发送的报文 state模块可以让iptables实现 连接追踪机制 NEW表 ...

  7. 用js刷剑指offer(字符串的排列)

    题目描述 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入 ...

  8. Alpha版本第二周小结

               软工作业---Alpha版本第二周小结   姓名 学号 周前计划 每周实际工作记录 自我打分 yrz 1417 协助原型设计的完善,督促组员完成个人任务 原型优化设计未完成,但体 ...

  9. brew install thrift

    ➜ ~ brew install thriftUpdating Homebrew...Warning: You are using macOS 10.11.We (and Apple) do not ...

  10. linux网络编程之socket编程(七)

    今天继续学习socket编程,北京在持续几天的雾霾天之后久违的太阳终于出来了,心情也特别特别的好,于是乎,在这美好的夜晚,该干点啥事吧,那当然就是继续坚持我的程序学习喽,闲话不多说,进入正题: 通过这 ...