当前位置:网站首页>[andorid] realize SPI communication between kernel and app through JNI
[andorid] realize SPI communication between kernel and app through JNI
2022-04-23 13:19:00 【Johnny2004】
about kernel Layer code ,Linux There is a classic reference driver in the original code , Can imitate spi drive .
If you don't ask too much , Just modify the equipment number and node name , Then you can talk to dts If the match is successful , Finally, remember to modify the generated node permissions
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 Your code needs to be completed by yourself ( Unwanted HAL layer ), And then JNI Add to App Chinese compiler .
The following code just realizes the simple read-write function , complete app and kernel Communication between , The complex part is the conversion between arrays .
JNI file name :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\n",*(buf + i));
}
(*env)->ReleaseByteArrayElements(env, jwrite_arr, array, 0);
write(fd, buf, len);
free(buf);
return 0;
}
Compile the file :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 The test code is also very simple , One is the main activity , One is with JNI link
MainActivity.java
// JNI The first part of the function name in should be the same as this
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");
}
}
Reference resources :
版权声明
本文为[Johnny2004]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230608014834.html
边栏推荐
- Melt reshape decast long data short data length conversion data cleaning row column conversion
- Armv8m (cortex M33) MPU actual combat
- ECDSA signature verification principle and C language implementation
- Stack protector under armcc / GCC
- Summary of request and response and their ServletContext
- [Technical Specification]: how to write technical documents?
- (personal) sorting out system vulnerabilities after recent project development
- Nodejs + Mysql realize simple registration function (small demo)
- torch. Where can transfer gradient
- web三大组件之Filter、Listener
猜你喜欢
AUTOSAR from introduction to mastery 100 lectures (86) - 2F of UDS service foundation
filter()遍历Array异常友好
Imx6ull QEMU bare metal tutorial 1: GPIO, iomux, I2C
[official announcement] Changsha software talent training base was established!
100000 college students have become ape powder. What are you waiting for?
Loading and using image classification dataset fashion MNIST in pytorch
初鉴canvas,展示个小小的小案例
Lpddr4 notes
The filter() traverses the array, which is extremely friendly
nodeJs + websocket 循环小案例
随机推荐
Introduction to metalama 4 Use fabric to manipulate items or namespaces
vscode小技巧
mui picker和下拉刷新冲突问题
three. JS text ambiguity problem
Analysis of the latest Android high frequency interview questions in 2020 (BAT TMD JD Xiaomi)
CMSIS cm3 source code annotation
Mui wechat payment pit
"Play with Lighthouse" lightweight application server self built DNS resolution server
Stack protector under armcc / GCC
Lpddr4 notes
Vscode tips
榜样专访 | 孙光浩:高校俱乐部伴我成长并创业
100 GIS practical application cases (34) - splicing 2020globeland30
torch. Where can transfer gradient
decast id.var measure. Var data splitting and merging
MySQL -- 16. Data structure of index
你和42W奖金池,就差一次“长沙银行杯”腾讯云启创新大赛!
CSDN高校俱乐部“名师高校行”——湖南师范大学站
2021年6月程序员工资统计,平均15052元,你拖后腿了吗?
超40W奖金池等你来战!第二届“长沙银行杯”腾讯云启创新大赛火热来袭!