Jni study
2019-2-18
在MTK6735平台下,在eclipse.exe中做几个按钮调用JNI层,控制GPIO7的LED,亮灭闪烁。
eclipse使用教程:https://jingyan.baidu.com/article/0a52e3f4e241a0bf62ed72a7.html
eclipse 开发 jni:https://blog.csdn.net/dg_summer/article/details/52880232
解决NDK开发中Eclipse报错“Unresolved inclusion jni.h”的最终方法:https://blog.csdn.net/xiaogazhang/article/details/46888781
一、JAVA的编写
E:/%E6%9C%89%E9%81%93%E4%BA%91%E7%AC%94%E8%AE%B0/weixinobU7VjiHeyJ5xDKs8qyaJ-NAI2_E/aa8aec0db74e478ba5a48d8f7dd1bb64/482.png
1、fragment_main.xml 如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="example.test.MainActivity$PlaceholderFragment" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="230dp"
android:layout_marginTop="0dp"
android:text="GPIO7 control"
android:textSize="50sp" />
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:layout_marginLeft="59dp"
android:layout_marginTop="250dp"
android:minHeight="100dip"
android:minWidth="120dip"
android:text="LED_ON" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button1"
android:layout_alignBottom="@+id/button1"
android:layout_centerHorizontal="true"
android:minHeight="100dip"
android:minWidth="120dip"
android:text="LED_OFF" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button2"
android:layout_alignBottom="@+id/button2"
android:layout_marginLeft="56dp"
android:layout_toRightOf="@+id/textView1"
android:minHeight="100dip"
android:minWidth="120dip"
android:text="LED_HZ" />
</RelativeLayout>
2、MainActivity.java 如下
package example.test;
import example.test.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
public class MainActivity extends Activity implements OnClickListener {
private TextView tv_text;
// 声明自定义本地库方法接口
public native int LEDON();//void不能写
public native int LEDOFF();
public native int LEDONOFF();
// 自动加载本地库文件,如文件名全称为 gpio.so
static{
System.loadLibrary("gpio");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//加载一个布局
setContentView(R.layout.fragment_main);
// 找到按钮
Button btn_call = (Button) findViewById(R.id.button1);
Button btn_call1 = (Button) findViewById(R.id.button2);
Button btn_call2 = (Button) findViewById(R.id.button3);
// 给button按钮设置一个点击事件
btn_call.setOnClickListener(this);
btn_call1.setOnClickListener(this);
btn_call2.setOnClickListener(this);
}
// 当点击按钮的时候执行
public void onClick(View v)
{
switch (v.getId())
{
case R.id.button1: LEDOFF(); System.out.println("1按钮被点击了"); break;
case R.id.button2: LEDON(); System.out.println("2按钮被点击了"); break;
case R.id.button3: LEDONOFF(); System.out.println("3按钮被点击了"); break;
default:
break;
}
}
}
3、JNI层编写
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS :=-llog
LOCAL_MODULE := gpio
LOCAL_SRC_FILES := gpio.cpp
include $(BUILD_SHARED_LIBRARY)
gpio.c:
#include <jni.h>
//#include <termios.h>
//#include <unistd.h>
//#include <sys/types.h>
//#include <sys/stat.h>
#include <fcntl.h>
//#include <string.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include <dirent.h>
//#include "mtk_gpio.h"
//#include <sys/ioctl.h>
#include <linux/ioctl.h>
//#include <errno.h>
#include <android/log.h>
#define TAG "BSK_MTK_GPIO"//过滤信息用的
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
#define ALOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型
//#define BSK_LED_ON _IOW('L', 1, unsigned long)
//#define BSK_LED_OFF _IOW('L', 2, unsigned long)
extern "C" {
JNIEXPORT jint JNICALL Java_example_test_MainActivity_LEDON(JNIEnv * env, jobject obj);
JNIEXPORT jint JNICALL Java_example_test_MainActivity_LEDOFF(JNIEnv * env, jobject obj);
JNIEXPORT jint JNICALL Java_example_test_MainActivity_LEDONOFF(JNIEnv * env, jobject obj);
// JNIEXPORT jint JNICALL Java_example_gpio_MainActivity_setmode(JNIEnv * env, jobject obj, jint port,jint mode);
// JNIEXPORT int JNICALL Java_com_bsk_xp6_MainActivity_Setthreshold(JNIEnv * env, jobject obj, jint channel);
};
JNIEXPORT jint JNICALL Java_example_test_MainActivity_LEDON(JNIEnv * env, jobject obj)
{
int fd,ret;
fd = open("/dev/led_device_file", O_RDWR);
if(fd < 0)
{
ALOGD("open led_drv fb = %d\n",fd);
return -1;
}
ret = ioctl(fd, 0x01, 1);//D1--on
if(ret < 0)
ALOGD("ioctl ret = %d\n",ret);
close(fd);
ALOGD("LED OFF !!!!!!!!!!!!!!!!!\n");
return 0;
}
JNIEXPORT jint JNICALL Java_example_test_MainActivity_LEDOFF(JNIEnv * env, jobject obj)
{
int fd,ret;
fd = open("/dev/led_device_file", O_RDWR);
if(fd < 0)
{
ALOGD("open led_drv\n");
return -1;
}
ret = ioctl(fd, 0x02, 1);//D1--off
if(ret < 0)
ALOGD("ioctl ret = %d\n",ret);
close(fd);
ALOGD("LED ON !!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
return 0;
}
JNIEXPORT jint JNICALL Java_example_test_MainActivity_LEDONOFF(JNIEnv * env, jobject obj)
{
int fd,ret,i;
fd = open("/dev/led_device_file", O_RDWR);
if(fd < 0)
{
ALOGD("open led_drv\n");
return -1;
}
ret = ioctl(fd, 0x01, 1);
if(ret < 0)
ALOGD("ioctl ret = %d\n",ret);
for(i=1; i<20; i++)
{
usleep(200*1000);
ioctl(fd, i%3, 1);
}
close(fd);
ALOGD("LED ON OFF !!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
return 0;
}
PS: cmd ---> cd App工程目录 ---> “ndk-build ”(该命令使cpp生成so)
二、调试JNI的内核调试打印手段
1、静态,输入以下命令 -》调试(按键按下) -》 ctrl+c退出 -》 查看输出信息
adb shell cat /proc/kmsg >1.txt
2、动态,命令过滤你的内核调试信息然后输出
grep "MTK*" /proc/kmsg
或者
cat /proc/kmsg | grep tttttttttttttttttttttt
三、其它问题描述
1、生成Android App时最少版本4.0以上就不会生成appcompat_v7项目(为了兼容低版本产生的)
2、eclipse编译apk的时候遇到问题,但没有提示,新建android工程提示:Failed to load properties file for project
解决:
Properties->Java ->Build Path->class path Varable
添加变量ANDROID_SDK_HOME,指向sdk目录。
但是编译时候卡住了,,,,
后来把workspace(工作空间)里的隐藏文件删了,所有工程重新导入,ok了。
|