一、编写JNI模块

当安装好NDK编译环境后,会在它的目录下找到sample目录,它里面有一些例子,可以参考这些例子来写我们自已的模块。

1、在/home/android/文件夹下,新建“ledjni”文件夹。

2、/ledjni/jni/目录下,新建“led-jni.c”

led-jni.c文件

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <jni.h>
  4. #include <fcntl.h> /*包括文件操作,如open() read() close()write()等*/
  5. #include <android/log.h>
  6. #define LOG_TAG "led-jni"
  7. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
  8. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
  9. #define DEVICE_NAME "/dev/led_by_wenhui" //device point
  10. //#define DEVICE_NAME "/dev/leds" //device point
  11. //#define DEVICE_NAME "/dev/led_" //device point
  12. #define LED_ON  1
  13. #define LED_OFF 0
  14. int fd;
  15. jstring Java_com_auly_control_ledClass_stringFromJNI( JNIEnv* env, jobject thiz )
  16. {
  17. return (*env)->NewStringUTF(env, "This is wenhui project ,Hello from JNI !");
  18. }
  19. jint Java_com_auly_control_ledClass_Init( JNIEnv* env)
  20. {
  21. LOGE("LEDclass_Init()\n");
  22. fd = open(DEVICE_NAME, 0);
  23. LOGE("LEDclass_Init()-> fd = %d \n", fd);
  24. if (fd < 0){
  25. LOGE("open device %s error \n", DEVICE_NAME);
  26. return 0;
  27. }
  28. return 1;
  29. }
  30. jint Java_com_auly_control_ledClass_IOCTL( JNIEnv* env, jobject thiz , jint ledID, jint ledState)
  31. {
  32. LOGE("IOCTL()-> %d ledState \n",ledState);
  33. LOGE("IOCTL()-> %d ledState \n",0);
  34. ioctl(fd,ledState, NULL);
  35. return 1;
  36. }
  37. jint Java_com_auly_control_ledClass_CLOSE( JNIEnv* env, jobject thiz )
  38. {
  39. close(fd);
  40. return 1;
  41. }
#include <stdio.h>
#include <string.h>
#include <jni.h>
#include <fcntl.h> /*包括文件操作,如open() read() close()write()等*/
#include <android/log.h>
#define LOG_TAG "led-jni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define DEVICE_NAME "/dev/led_by_wenhui" //device point
//#define DEVICE_NAME "/dev/leds" //device point
//#define DEVICE_NAME "/dev/led_" //device point
#define LED_ON 1
#define LED_OFF 0 int fd; jstring Java_com_auly_control_ledClass_stringFromJNI( JNIEnv* env, jobject thiz )
{
return (*env)->NewStringUTF(env, "This is wenhui project ,Hello from JNI !");
} jint Java_com_auly_control_ledClass_Init( JNIEnv* env)
{
LOGE("LEDclass_Init()\n");
fd = open(DEVICE_NAME, 0);
LOGE("LEDclass_Init()-> fd = %d \n", fd);
if (fd < 0){
LOGE("open device %s error \n", DEVICE_NAME);
return 0;
} return 1;
} jint Java_com_auly_control_ledClass_IOCTL( JNIEnv* env, jobject thiz , jint ledID, jint ledState)
{
LOGE("IOCTL()-> %d ledState \n",ledState);
LOGE("IOCTL()-> %d ledState \n",0);
ioctl(fd,ledState, NULL);
return 1;
} jint Java_com_auly_control_ledClass_CLOSE( JNIEnv* env, jobject thiz )
{
close(fd);
return 1;
}

3、相同目录下的新建Android.mk如下

Android.mk文件

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE    := led-jni
  4. LOCAL_SRC_FILES := led-jni.c
  5. LOCAL_CFLAGS := -Werror
  6. LOCAL_LDLIBS := -llog -lGLESv2
  7. include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := led-jni
LOCAL_SRC_FILES := led-jni.c
LOCAL_CFLAGS := -Werror
LOCAL_LDLIBS := -llog -lGLESv2 include $(BUILD_SHARED_LIBRARY)

可以看到,主要是修改LOCAL_SRC_FILES指向源文件的名称!

还有一点很重要,如果要使用调试LOG打印,也就是__android_log_print函数。要在LOCAL_LDLIBS中添加-llog,如上面的Android.mk所示。

4、编译JNI模块

#cd /home/android/ledjni

进到刚才写的JNI目录

#ndk-build

编译JNI,编译成功后,会在ledjni文件夹下生成libs和obj两个文件夹,并在

ledjni/libs/armeabi下得到目标文件libled-jni.so

(目前ledjni文件夹只有3个目录jni,libs,obj)

二、JAVA程序

1、Eclipse新建工程 LEDAPP

注意   Location: 选刚才的 ledjni

然后 Runas > Android application,就会出现android的模拟器了,里面跑个helloworld出来。

2、加入button和文本输出

程序到上面为止代码是ADT自动生成的,似乎与我们一点关系也没有。那我们来改一下代码,因为我们调用JNI接口是为了访问驱动程序操作硬件的,例如写,读,打开LED,关闭LED等等,由按钮触发的动作。

第一步是,增加两个Button,,在main.xml里描述一下:打开Res> layout> main.xml 文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="@string/hello"
  11. />
  12. <Button android:id="@+id/led_on"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. android:text="@string/LEDon"
  16. />
  17. <Button android:id="@+id/led_off"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:text="@string/LEDoff"
  21. />
  22. </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/> <Button android:id="@+id/led_on"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/LEDon"
/> <Button android:id="@+id/led_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/LEDoff"
/> </LinearLayout>

实际代码中,把注释去掉,否则编译不过的。

3、加入输出字符串资源

工程 >values > strings.xml文件

修改如下

<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<stringname="hello">Led控制程序</string>
<stringname="app_name">LEDAPP</string>
<stringname="LEDon">打开LED</string>
<stringname="LEDoff">关闭LED</string>
</resources>

上面的”打开LED”等资源,就是用在按钮上显示出来的字符串

经过上面的修改,现在程序界面上,已经有如下效果了

鼠标右键工程名>Runas > Android application运行程序。

4、加入按钮对应的动作

“关闭LED”按钮:

“打开LED”按扭:调用JNI的IOCTL(int ledID, int ledState);

操作:

在LEDAPP> src > com.auly.control >LEDAPPActivity.java文件

  1. package com.auly.control;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.view.View.OnClickListener;
  6. import android.widget.Button;
  7. public class LEDAPPActivity extends Activity {
  8. /** Called when the activity is first created. */
  9. //定义变量
  10. public static final int LED_ON = 0X01;
  11. public static final int LED_OFF = 0x00;
  12. private  Button btn1 = null;
  13. private  Button btn2 = null;
  14. //定义类
  15. ledClass myledclass;
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. // TODO Auto-generated method stub
  19. super.onCreate(savedInstanceState);
  20. //初始化
  21. setContentView(R.layout.main);
  22. myledclass = new ledClass();   //声明类
  23. myledclass.Init();             //调用JNI库里的初始化函数
  24. //按钮 打开 led
  25. btn1 = (Button)findViewById(R.id.led_on);
  26. btn1.setOnClickListener(new MyBtn1Listener());  //捆绑监听器
  27. //按钮 关闭 led
  28. btn2 = (Button)findViewById(R.id.led_off);
  29. btn2.setOnClickListener(new MyBtn2Listener());  //捆绑监听器
  30. }
  31. class MyBtn1Listener implements OnClickListener {
  32. @Override
  33. public void onClick(View v) {
  34. myledclass.Init();
  35. System.out.println("debug LED_ON");
  36. myledclass.IOCTL(0,LED_ON);
  37. }
  38. }
  39. class MyBtn2Listener implements OnClickListener {
  40. @Override
  41. public void onClick(View v) {
  42. System.out.println("debug LED_OFF");
  43. myledclass.IOCTL(0,LED_OFF);
  44. myledclass.CLOSE();
  45. }
  46. }
  47. }
package com.auly.control;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; public class LEDAPPActivity extends Activity {
/** Called when the activity is first created. */
//定义变量
public static final int LED_ON = 0X01;
public static final int LED_OFF = 0x00;
private Button btn1 = null;
private Button btn2 = null; //定义类
ledClass myledclass; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState); //初始化
setContentView(R.layout.main);
myledclass = new ledClass(); //声明类
myledclass.Init(); //调用JNI库里的初始化函数 //按钮 打开 led
btn1 = (Button)findViewById(R.id.led_on);
btn1.setOnClickListener(new MyBtn1Listener()); //捆绑监听器 //按钮 关闭 led
btn2 = (Button)findViewById(R.id.led_off);
btn2.setOnClickListener(new MyBtn2Listener()); //捆绑监听器
} class MyBtn1Listener implements OnClickListener {
@Override
public void onClick(View v) {
myledclass.Init();
System.out.println("debug LED_ON");
myledclass.IOCTL(0,LED_ON);
}
} class MyBtn2Listener implements OnClickListener {
@Override
public void onClick(View v) {
System.out.println("debug LED_OFF");
myledclass.IOCTL(0,LED_OFF);
myledclass.CLOSE();
}
}
}

5、添加类ledClass

鼠标右键com.auly.control> new > Class

填参数:

Finish后,在/src/com/auly/control/得到如下的类文件

ledClass.java

修改如下

package com.auly.control;

public class ledClass {
    /*声明函数*/
    //初始化函数 对应 JNI 里面的 jint Java_com_auly_control_ledClass_Init( JNIEnv* env) 函数 以下的同理
    public native int Init();
    public native int IOCTL(int ledID, int ledState);
    public native String stringFromJNI();
    public native int CLOSE();
    static{
        System.loadLibrary("led-jni");/*加载JNI库*/
    }
}

三、 编译运行

鼠标右键工程名,弹出菜单,选择 Runas > Android Application就可以看到编译过程,编译完成后,会自动调用android模拟器,看到界面效果

安装到开发板:(方式有多种 adb ) 或直接用u盘拷贝(这样调试比较麻烦)

在LEDSJNI目录下,会看到bin文件夹,里面的LEDAPP.apk就是这个程序的安装文件,可以把它安装的开发板上,运行本程序,看控制开发板上的LED灯的效果。

注意!运行前 要修改的驱动节点的权限

#chmod777 /dev/vib

这是为了使得led_by_wenhui这个节点可以被我们写的JNI操作,不然会open失败的,因为APK安装的JNI模块,权限不够,这个节点是我们的LED驱动生成的控制节点。

也可以在android文件系统yaffs编译时,通过init.rc文件来实现这个操作,就是在该文件里随便一行,写上面的命令行,启动时会自动执行!这样就不用手动的改变该节点的属性了。

拷贝LEDAPP.apk到开发板上,通过安装工具把它安装到开发板上

运行程序,就能按程序上的近钮来控制开发板上的LED亮灭了!

mini6410-JNI-led的更多相关文章

  1. 嵌入式Linux驱动开发日记

    嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...

  2. ok6410 android driver(12)

    In this essay, I will talk about how to write the service libraries. TIPS : I won't discuss the name ...

  3. Android Mokoid Open Source Project hacking

    /***************************************************************************** * Android Mokoid Open ...

  4. 〖Android〗OK6410a的Android HAL层代码编写笔记

    一.编写LED灯的Linux驱动程序代码 之所以使用存在HAL层,是为了保护对硬件驱动过程的逻辑与原理: 所以,残留在Linux驱动层的代码,只保留了基本的读写操作,而不含有关键的逻辑思维: 1. l ...

  5. 关于Android的HAL的一些理解

    之前一直在学习基于Linux内核的一些字符型驱动的编程,对Linux内核驱动也算有了一些基本的了解吧,后来也做过一些基于Linux内核的驱动开发,像基于Android的CC1101高频模块的驱动开发, ...

  6. ARM入门实践(一)----Mini6410上最简单的LED点灯裸机程序

    Mini6410上最简单的LED点灯裸机程序 : 实验环境: 根据友善教程,要用ADS,据说现在都不用这个了,但是为了打开友善给的mcp工程,就下了一个,Win7下弄上兼容模式和管理员权限,再下一个S ...

  7. LED硬件访问服务(2)——JNI/HAL

    一.系统编程 1.SystemServer.java类中提供了main()方法,说明它是以一个进程的方式存在的,启动后直接执行其run() 2.注册服务ServiceManager.addServic ...

  8. Android驱动入门-Led控制+app+ndk库+底层驱动

    硬件平台: FriendlyARM Tiny4412 Cortex-A9 操作系统: UBUNTU 14.04 LTS 时间:2016-09-20  21:56:48 本次实验使用的是 安卓APP + ...

  9. 深入浅出 - Android系统移植与平台开发(十) - led HAL简单设计案例分析

    作者:唐老师,华清远见嵌入式学院讲师. 通过前两节HAL框架分析和JNI概述,我们对Android提供的Stub HAL有了比较详细的了解了,下面我们来看下led的实例,写驱动点亮led灯,就如同写程 ...

  10. [LED]如何配置LCD背光和LED,调试方法

    [DESCRIPTION] 如何配置LCD背光和LED,调试方法 [SOLUTION]LCD背光和LED配置文件alps/custom/<proj name>lk/cust_leds.ca ...

随机推荐

  1. Linux下的多进程编程

    1.进程 1.1进程的定义 <计算机操作系统>这门课对进程有这样的描述:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统 ...

  2. C++ STL 简单记录

    1,STL提供三种类型的组件:容器.迭代器.算法. 容器: 顺序容器(vector.list.deque.string等)是一系列元素的有序集合: 关联容器(set.multiset.map.mult ...

  3. 比特币钱包应用breadwallet源码

    breadwallet是一款安全.可靠和便捷的比特币钱包,可使用户免于恶意软件和其他应用中常见的安全问题的骚扰,充分利用了iOS提供的安全功能,包括AES硬件加密.app沙盒和数据保护.代码签名以及k ...

  4. php的命名规范

    1.类 类名每一个单词首字母大写,如类名StudentCourse. 2.常量 常量名所有字母大写,单词间用下划线分隔,如常量名NULL.TRUE.FALSE.ROOT_PATH等. 3.变量 为了保 ...

  5. IntelliJ IDEA 快捷键和设置

    IntelliJ IDEA 使用总结 http://my.oschina.net/xianggao/blog/97539 IntelliJ IDEA 问题解决:1.乱码,主要是快捷键的字样显示乱码 中 ...

  6. Web前端代码规范与页面布局

    一.    规范目的: 为提高工作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档,在网站建设中,使结构更加清晰,代码简明有序,有一个更好的前端架构,有利于SEO优化.   二.     ...

  7. j-query j-query

    jQuery   1.安装:http://jquery.com/download/登陆这个jQuery下载2在.html文件的<head>标签中导入3 语法$(selector).acti ...

  8. 关于ASP.net TextBox控件的失去焦点后触发其它事件

    编写人:CC阿爸 2015-2-02 今天在这里,我想与大家一起分享如何处理的ASP.net TextBox控件的失去焦点后触发其它事件的问题,在此做个小结,以供参考.有兴趣的同学,可以一同探讨与学习 ...

  9. linux常用命令--ps、netstat、find

     一.ps 1.1ps命令简介 Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那 ...

  10. 三、MongoDB的创建、更新和删除

    一.MongoDB的下载.安装与部署 二.MongoDB的基础知识简介 三.MongoDB的创建.更新和删除 概要 下面开始学习MongoDB最重要也是最基础的部分:C(创建)R(查询)U(更新)D( ...