CPU:RK3399

系统:Android 7.1

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

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

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

path:kernel/drivers/spi/spidev.c

  1. diff --git a/device/rockchip/common/ueventd.rockchip.rc b/device/rockchip/common/ueventd.rockchip.rc
  2. index 8d5d28d..4b6ac2a 100644
  3. --- a/device/rockchip/common/ueventd.rockchip.rc
  4. +++ b/device/rockchip/common/ueventd.rockchip.rc
  5. @@ -65,6 +65,8 @@
  6. /dev/ttyS2 0666 system system
  7. /dev/ttyS3 0666 system system
  8.  
  9. +/dev/thm36 0666 system system
  10. +
  11. # for radio
  12. /dev/ttyUSB0 0660 radio radio
  13. /dev/ttyUSB1 0660 radio radio

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

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

JNI 文件名:thm36_jni.c

  1. #include <jni.h>
  2. #include <stdio.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. #include <termios.h>
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <string.h>
  12.  
  13. #include "android/log.h"
  14.  
  15. static const char *TAG = "thm36_jni";
  16.  
  17. #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)
  18. #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
  19. #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
  20.  
  21. #define DEV_NAME "/dev/thm36"
  22.  
  23. static jint fd;
  24.  
  25. JNIEXPORT jint JNICALL Java_com_example_aaron_se_Thm36Native_thm36Open(JNIEnv *env, jclass clazz)
  26. {
  27. LOGD("JNI spi open ... ...");
  28.  
  29. fd = open(DEV_NAME, O_RDWR);
  30. if (fd < )
  31. {
  32. LOGD("open device fail!");
  33. return -;
  34. }
  35.  
  36. return ;
  37. }
  38.  
  39. JNIEXPORT void JNICALL Java_com_example_aaron_se_Thm36Native_thm36Close(JNIEnv *env, jclass clazz)
  40. {
  41. LOGD("JNI spi close ... ...");
  42.  
  43. close(fd);
  44. }
  45.  
  46. JNIEXPORT jint JNICALL Java_com_example_aaron_se_Thm36Native_thm36Read(JNIEnv *env, jclass clazz, jbyteArray jread_arr, jint len)
  47. {
  48. jbyte *array = NULL;
  49. jboolean *buf;
  50. int i = ;
  51.  
  52. LOGD("JNI spi read ... ...");
  53.  
  54. array = (*env)->GetByteArrayElements(env, jread_arr, NULL);
  55. if (array == NULL)
  56. {
  57. LOGD("JNI spi read: GetByteArrayElements faid!");
  58. return -;
  59. }
  60.  
  61. buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
  62. if (buf == NULL)
  63. {
  64. LOGD("JNI spi read: calloc fail!");
  65. return -;
  66. }
  67.  
  68. read(fd, buf, len);
  69. for (i=; i<len; i++)
  70. {
  71. LOGD("JNI spi read: buf: %#x", *(buf + i));
  72. *(array + i) = (jchar)(*(buf + i));
  73. }
  74.  
  75. (*env)->ReleaseByteArrayElements(env, jread_arr, array, );
  76.  
  77. free(buf);
  78.  
  79. return ;
  80. }
  81.  
  82. JNIEXPORT jint JNICALL Java_com_example_aaron_se_Thm36Native_thm36Write(JNIEnv *env, jclass clazz, jbyteArray jwrite_arr, jint len)
  83. {
  84. jbyte *array = NULL;
  85. jboolean *buf;
  86. int i = ;
  87.  
  88. LOGD("JNI spi write ... ...");
  89.  
  90. array = (*env)->GetByteArrayElements(env, jwrite_arr, NULL);
  91. if (array == NULL)
  92. {
  93. LOGD("JNI spi write: GetByteArrayElements fail!");
  94. return -;
  95. }
  96.  
  97. buf = (jboolean *)calloc(sizeof(*array), sizeof(jboolean));
  98. if(buf == NULL)
  99. {
  100. LOGD("JNI spi write: calloc fail!");
  101. return -;
  102. }
  103.  
  104. for(i = ; i < len; i++)
  105. {
  106. *(buf + i) = (jboolean)(*(array + i));
  107. LOGD("JNI spi write: data : %#x\n",*(buf + i));
  108. }
  109.  
  110. (*env)->ReleaseByteArrayElements(env, jwrite_arr, array, );
  111.  
  112. write(fd, buf, len);
  113.  
  114. free(buf);
  115.  
  116. return ;
  117. }

编译文件:Android.mk

  1. LOCAL_PATH := $(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. TARGET_PLATFORM := android-3
  6. LOCAL_MODULE := thm36_jni
  7. LOCAL_SRC_FILES := thm36_jni.c
  8. LOCAL_LDLIBS := -llog
  9.  
  10. include $(BUILD_SHARED_LIBRARY)

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

MainActivity.java

  1. // JNI中的函数名前面部分要与此相同
  2. package com.example.aaron.se;
  3.  
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.util.Log;
  7. import android.view.View;
  8. import android.widget.Button;
  9.  
  10. public class MainActivity extends AppCompatActivity implements View.OnClickListener{
  11.  
  12. Thm36Native thm36 = new Thm36Native();
  13. byte[] tx = {(byte)0xAA, 0x00, 0x06, 0x00, (byte)0xCA, 0x00, 0x00, 0x00, 0x00, (byte)0xCA};
  14. byte[] rx = new byte[22];
  15.  
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20.  
  21. Button btn = (Button) findViewById(R.id.btn);
  22.  
  23. btn.setOnClickListener(MainActivity.this);
  24. }
  25.  
  26. @Override
  27. public void onClick(View view) {
  28. switch (view.getId()) {
  29. case R.id.btn:
  30. thm36.thm36Open();
  31. thm36.thm36Write(tx, tx.length);
  32. thm36.thm36Read(rx, rx.length);
  33. thm36.thm36Close();
  34. break;
  35.  
  36. default:
  37. break;
  38. }
  39. }
  40. }

Thm36Native.java

  1. package com.example.aaron.se;
  2.  
  3. import android.util.Log;
  4.  
  5. public class Thm36Native {
  6.  
  7. private final String TAG = "Thm36Native";
  8.  
  9. public native int thm36Open();
  10. public native void thm36Close();
  11. public native int thm36Read(byte[] buf, int len);
  12. public native int thm36Write(byte[] buf, int len);
  13.  
  14. static {
  15. System.loadLibrary("thm36");
  16. }
  17. }

参考:

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. cookie和session以及iOS cookie的查取

    Cookie的工作原理 http是无状态的,这是什么意思呢?就是说,在没有cookie之前,你第一次访问这个页面和第二次访问这个页面, 服务器是不知道的,不知道前一次是你.那么问题来了,我怎么登录,登 ...

  2. redis连接数高居不下,怎么破?。。。。这么破

    最近项目一直在使用redis,首次用redis,随便从网上找了例子就用了,一开始用的还挺正常,后来发现,当客户端访问量一上来,redis的连接数居高不下,一开始以为是客户端没有关闭,开始怀疑redis ...

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

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

  4. Python函数Day6

    一.内置函数 list() 将一个可迭代对象转化为列表 字典转为列表:会将所有键转化为列表 字符串转为列表:键每个字符转化为列表 s = 'abc' dic = {'a':1,'b':2,'c':3} ...

  5. Vue中的button事件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. maven 打包到本地库

    mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.2.0 -Dpackaging= ...

  7. JDK环境变量配置window

    下面开始配置环境变量,右击[我的电脑]---[属性]-----[高级]---[环境变量],如图: ​选择[新建系统变量]--弹出“新建系统变量”对话框,在“变量名”文本框输入“JAVA_HOME”,在 ...

  8. Linux网络编程综合运用之MiniFtp实现(三)

    前面已经对FTP相关的一些概念有了基本的认识,接下来就要进入代码编写阶段了,也是非常兴奋的阶段,在开启这个它之前先对项目需求进行一个梳理,对其我们要实现的FTP服务器是一个什么样子. ftp命令列表 ...

  9. Mybatis的简单搭建

    1.官方网址 http://www.mybatis.org/mybatis-3/zh/getting-started.html 2.导入jar包 3.根据官方文档,首先写mybatis-config. ...

  10. 使用UEditor 报错Cannot read property 'nodeType' of undefined 解决办法

    报如下错误 解决办法: //对编辑器的操作最好在编辑器ready之后再做 ue.ready(function() { }) <!-- 实例化编辑器 --> <script type= ...