mini6410-JNI-led

一、编写JNI模块

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

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

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

led-jni.c文件

[html] view
plaincopyprint?

  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文件

[html] view
plaincopyprint?

  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 文件

[html] view
plaincopyprint?

  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文件

[html] view
plaincopyprint?

  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,码迷,mamicode.com

时间: 2024-07-30 10:17:00

mini6410-JNI-led的相关文章

Android底层开发(二)之JNI层

1 源文件LedHalService.cpp #include <stdlib.h> #include <string.h> #include <unistd.h> #include <assert.h> #include <jni.h> #include <leds_hal.h> struct led_control_device_t *led_hal_device = NULL; static jboolean led_setOn

Android Mokoid Open Source Project hacking

/***************************************************************************** * Android Mokoid Open Source Project hacking * * 声明: * 1. 本文主要是为了了解Android HAL工作机制,从而决定分析mokoid开源项目: * 2. 源代码URL:https://code.google.com/p/mokoid/source/checkout: * 3. 本文通

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

Mini6410上最简单的LED点灯裸机程序 : 实验环境: 根据友善教程,要用ADS,据说现在都不用这个了,但是为了打开友善给的mcp工程,就下了一个,Win7下弄上兼容模式和管理员权限,再下一个SecureCRT代替超级终端. 一定要,把AXD也设置上. secureCRT的配置:选择Serial串口,波特率115200,端口号:USB转串(去驱动程序查端口号,今天插了一个COM4,一个COM5) 实验步骤: 配置好了以后,打开CodeWarrior编译mini6410-led.bin文件

Tiny4412 led之JNI实现

硬件平台:Tiny4412标准版+android5.0 Tiny4412硬件电路 从电路原理图可以知道LED灯连接到处理器的GPM4的0-3端口,且LED被上拉到3.3V的源,只有GPIO口输出低电平时就能点亮LED灯: GPM4寄存器 只要把GPM4CON对应的区域设置为0x1且GPM4DAT对应bit设置为0,则IO口就会输出低电平: 编写led驱动程序 tiny4412_leds.c #include <linux/init.h> #include <linux/kernel.h&

基于TINY4412的Andorid开发-------简单的LED灯控制【转】

本文转载自:http://www.cnblogs.com/pengdonglin137/p/3857724.html 基于TINY4412的Andorid开发-------简单的LED灯控制 阅读目录(Content) 一.编写驱动程序 二.编写代码测试驱动程序 三.编写HAL代码 四.编写Framework代码 五.编写JNI代码 六.编写App 参考资料: <Andriod系统源代码情景分析> <嵌入式Linux系统开发完全手册_基于4412_上册> 作者:彭东林 邮箱:[em

自己动手写最简单的Android驱动---LED驱动的编写【转】

本文转载自:http://blog.csdn.net/k_linux_man/article/details/7023824 转载注明出处,作者:K_Linux_Man, 薛凯 山东中医药大学,给文章内容引入个人毕业设计. 开发平台:farsight s5pc100-a 内核:linux2.6.29 环境搭配:有博文介绍 开发环境:Ubuntu .Eclipse 首先强调一下要点: 1.编写Android驱动时,首先先要完成Linux驱动,因为android驱动其实是在linux驱动基础之上完成

android之APP+JNI+Drv框架

以LED为例 APP: JNI之java JNI之c DRV 项目组成:1.应用部分 1.1 APK(android工程) 1.1.1 java(功能) 1.1.2 xml(界面) 1.1.3 JNI(自带) 1.1.4 动态库(驱动接口) 1.1.1.4.1 JNIEXPORT jint JNICALL 1.1.1.4.2 JNI_OnLoad 1.1.1.4.3 JNINativeMethod 1.1.1.4.4 c_fun2.驱动部分 2.1 驱动实体 编译流程:1.编译内核(驱动)2.编

Tiny4412 LED 硬件服务

1.Android系统中启动框架 2.首先实现驱动程序 #include <linux/kernel.h> #include <linux/module.h> #include <linux/miscdevice.h> #include <linux/device.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/moduleparam.h>

有注释的LED驱动

裸机下控制LED灯非常方便,只需要配置好GPIO引脚功能,然后向GPIO引脚映射的内存地址处写入数据即可,但linux下驱动就不那么简单了,需要结合字符设备驱动的架构,然后将功能实现添加进去,笔者参考linux设备驱动程序(第三版)中介绍的新的接口来实现驱动.友善之臂官网提供的源码是基于miscdevice的驱动,而且接口似乎有点老,比如在linux设备驱动程序(第三版)中强调需要使用新的内存I/O接口来访问映射内存,建议使用ioread32,iowrite32等,但是它依然使用writel,r

Android 4.4.2 动态加入JNI库方法记录 (一 JNI库层)

欢迎转载,务必注明出处.http://blog.csdn.net/wang_shuai_ww/article/details/44456755 本篇是继<s5p4418 Android 4.4.2 驱动层 HAL层 服务层 应用层 开发流程记录>之后的第二种加入JNI和服务的方法. 前面的方法是直接把HAL和服务层加入到了.Android的api中.这种方式优点是操作系统已开发完毕,剩下做APP的开发,那么我们仅仅须要一个classes.jar文件就可以使用我们自己Android系统的被隐藏的