`

JNI综合实验二:IO控制及驱动打开与关闭

 
阅读更多

第一步:首先在linux下添加驱动

1.查看原理图,找出未使用的引脚,这里是:GPJ0_0 GPJ0_1

2.添加char字符设备驱动,找到LINUX源代码下的char设备驱动路径: FriendlyArm /Linux3.0.8/ Drivers/char/目录,在目录下新建里一个文件lzm_fjicc.c 用来写驱动用。

需要注册设备、设备的打开、关闭、取消设备等操作。

源代码如综合实验一:

 

第二步:建立Android测试代码,第一步要实现.so文件:

1.打开eclipseàFileàNewàAndroid Application Project  com.example.TEST

2.新建jni文件夹,在文件夹内新建两个文件:test-jni.cAndroid.mk

Android.mk内容如下:

# Copyright (C) 2009 The Android Open Source Project

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

#      http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

#

LOCAL_PATH := $(call my-dir)

 

include$(CLEAR_VARS)

 

LOCAL_MODULE    := test-jni

LOCAL_SRC_FILES := test-jni.c

 

include$(BUILD_SHARED_LIBRARY)

jni0922.c内容如下:

/*

 * Copyright (C) 2009 The Android Open Source Project

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *      http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 *

 */

#include<termios.h>

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<sys/ioctl.h>

#include<fcntl.h>

#include<string.h>

#include<jni.h>

#include<errno.h>

//#include <utils/Log.h>

//#include <system.h>

 

#define VIB_ON 0x11

#define VIB_OFF 0x22

 

 

 

#define  DEV_NAME "/dev/LZM_FJICC"

/* This is a trivial JNI example where we use a native method

 * to return a new VM String. See the corresponding Java source

 * file located at:

 *

 *   /project/app/TEST/src/com.example.TEST/MainActivity.java

 *   /project/app/TEST/src/com.example.TEST/TESTCLASS.java

 */

jstring

Java_com_example_TEST_TESTCLASS_stringFromJNI( JNIEnv* env, jobject thiz )

{

    return (*env)->NewStringUTF(env, "Hello from JNI !");

}

 

jint

Java_com_example_TEST_TESTCLASS_IOCTL( JNIEnv* env, jobject thiz, jint fd ,jint controlcode,jint ledid)

{

       /* LED */

    int CTLCODE = controlcode;

    int value =-1;

    switch(CTLCODE)

    {  case VIB_ON:

              {

              ioctl(fd,1,ledid);//setLedState( 0, 1 );//调用驱动程序中的ioctrl接口,把命令传下去,实现硬件操作

              break;

              }

       case VIB_OFF:

             {

              ioctl(fd,0,ledid);////     setLedState( 0, 0 );//调用驱动程序中的ioctrl接口,把命令传下去,实现硬件操作

             break;

             }

 

       default:break;

     }

       return fd;

}

 

jint

Java_com_example_TEST_TESTCLASS_OPEN(JNIEnv* env,jobject thiz)

{

 

      jint fd;

      fd=open(DEV_NAME,O_RDWR);

      return fd;

}

 

jint

Java_com_example_TEST_TESTCLASS_CLOSE( JNIEnv* env, jobject thiz, jint fd)

{

        jint ret;

        ret = close(fd);

        return ret;

}

 

 

注意如果需要头文件Alog.h需要自己写,然后放在jni文件夹下的

#pragma once

#include<android/log.h>

#define LOG_TAG "debug log"

#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)

#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)

#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args)

 

 

 

3.建立完毕,打开Cygwin工具,并进入到工程目录下的jni目录下:

$ cd d:/Program/Android/workspace/TEST /jni

$$NDK/ndk-build

 

这样就OK了,生成了libtest-jni.so文件了,自动生成到了工程目录下的libs/armeabi/ libtest-jni.so,发现test-jni是我们刚才在.mk文件里面的命名。

 

第三步:写应用程序:

1.在应用程序类com.example.TEST目录下建立一个类:TESTCLASS.java,输入如下代码,这是用来引用libtest-jni.so文件的。

package com.example.TEST;

 

import android.util.Log;

 

publicclass TESTCLASS {

 

public  native String stringFromJNI();

public  nativeint OPEN();

public  nativeint IOCTL(int fd,int controlcode,int ledID);

public  nativeint CLOSE(int fd);

 

static {

    try {

    System.loadLibrary("test-jni");

    } catch (UnsatisfiedLinkError e) {

        Log.d("HardwareControler", "HardwareControler ibrary not found!");

    }

}

}

 

2.编写应用程序,调用TESTCLASS类中的函数OPEN()/CLOSE()/IOCTL()就可以实现底层的控制了。

添加按钮,用来打开和关闭LED,以及关闭驱动

<Button

            android:id="@+id/button1"

            style="?android:attr/buttonStyleSmall"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="center_horizontal"

            android:layout_weight="0.76"

            android:text="ON" />

 

        <Button

            android:id="@+id/button2"

            style="?android:attr/buttonStyleSmall"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="1.26"

            android:text="OFF" />

 

        <Button

            android:id="@+id/button5"

            style="?android:attr/buttonStyleSmall"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="0.76"

            android:text="close" />

2.编写MainActivity,添加响应函数:

package com.example.TEST;

 

import java.io.DataOutputStream;

import java.io.IOException;

 

import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;

import android.view.View;

import android.widget.Button;

import android.widget.Toast;

 

publicclass MainActivity extends Activity {

 

    private Button btn_on;

    private Button btn_off,btn_close;

   

    publicstaticfinalintVIB_ON = 0x11; 

    publicstaticfinalintVIB_OFF = 0x22;  

    intfd;

    intvalue = -1;

    TESTCLASS mTESTCLASS1;

   

    @Override

    protectedvoid onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

      

       setContentView(R.layout.activity_main);

       mTESTCLASS1 = new TESTCLASS();

       String s = mTESTCLASS1.stringFromJNI().toString();

      

       //修改驱动的权限LZM_FJICC

       changePerm();

             

             

       fd = mTESTCLASS1.OPEN();

       Toast.makeText(MainActivity.this, "open,fd="+fd, Toast.LENGTH_SHORT).show();

      

       btn_on = (Button)findViewById(R.id.button1);

       btn_off = (Button)findViewById(R.id.button2);   

       btn_close= (Button)findViewById(R.id.button5);

      

      

      

      

       if(fd == -1)

           Toast.makeText(MainActivity.this, "没有打开设备", Toast.LENGTH_SHORT).show();

       else

           Toast.makeText(MainActivity.this, "打开设备", Toast.LENGTH_SHORT).show();

      

       Toast.makeText(MainActivity.this,""+s, Toast.LENGTH_SHORT).show();

      

       btn_on.setOnClickListener(new Button.OnClickListener(){

 

           @Override

           publicvoid onClick(View arg0) {

              // TODO Auto-generated method stub

              fd=mTESTCLASS1.IOCTL(fd, VIB_ON,0);

              Toast.makeText(MainActivity.this, "ioctl,fd="+fd, Toast.LENGTH_SHORT).show();

           }

       });

      

      

       btn_off.setOnClickListener(new Button.OnClickListener(){

 

           @Override

           publicvoid onClick(View v) {

              // TODO Auto-generated method stub

              mTESTCLASS1.IOCTL(fd, VIB_OFF,0);

 

           }});

      

      

      

       btn_close.setOnClickListener(new Button.OnClickListener(){

 

           @Override

           publicvoid onClick(View v) {            

           // TODO Auto-generated method stub

              Toast.makeText(MainActivity.this, "close,fd="+fd, Toast.LENGTH_SHORT).show();

              if(fd != -1){

                     value = mTESTCLASS1.CLOSE(fd);

                     if(value == -1)

                         Toast.makeText(MainActivity.this, "close fail,fd="+value, Toast.LENGTH_SHORT).show();

                     else

                         Toast.makeText(MainActivity.this, "close success,fd="+value, Toast.LENGTH_SHORT).show();

              }else{

              Toast.makeText(MainActivity.this, "设备未打开,无需关闭", Toast.LENGTH_SHORT).show();

              }

           }

          

       });

      

   

    }

   

    void changePerm()

    {

        Process chperm;

        try {

            chperm=Runtime.getRuntime().exec("su");

 

 

       DataOutputStream os =

              new DataOutputStream(chperm.getOutputStream());

            os.writeBytes("chmod 777 /dev/LED_LZM_FJICC\n");

            os.flush();

 

            os.writeBytes("exit\n");

            os.flush();

 

              chperm.waitFor();

 

    } catch (IOException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    } catch (InterruptedException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

    }

}

问题一:android NDK jni下的c文件 Unresolved inclusion

原因是在eclipse编辑环境中没有找到对应的include中的文件。解决方法是将包含该文件的include目录作为新的linked folder加入工程中。具体方法如下:
1.
右击工程->New->Folder

2. 对话框中点击Advanced

3. 选择Link to alternate location (Linked Folder),选择需要的include目录

4. Finish后刷新工程,问题解决。

include 目录可以在ndk的安装目录中找到

比如:在安装的NDK目录下找到/NDKDir/android-ndk-r7b/platforms/android-8/arch-arm/usr/include

 

问题二:在android 里使用JNI,总是报错:in something not a structure or union

 error: request for member 'GetStringUTFChars' in something not a structure or union

问题解决了,原来是这样的:
如果是c程序,要用 (*env)->
如果是C++要用 env->

linux下如果.c文件中用 “env->” 编译会找不到此结构,必须用“(*env)->”,或者改成.cpp文件,以 c++的方式来编译

以下是两者的区别:
jni.h

struct JNINativeInterface_;
struct JNIEnv_;
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif

/*
* We use inlined functions for C++ so that programmers can write:
*   env->FindClass("java/lang/String")
* in C++ rather than:
*    (*env)->FindClass(env, "java/lang/String")
* in C.
*/
C++中使用
env->FindClass("java/lang/String")
C
中使用
(*env)->FindClass(env, "java/lang/String")

 

 

问题三:直接在应用程序中获取驱动的可执行权限#chmod 777

//用来修改驱动的权限问题否则需要在终端输入 #chmod 777 /dev/LZM_FJICC

    void changePerm()

    {

        Process chperm;

        try {

            chperm=Runtime.getRuntime().exec("su");

       DataOutputStream os =

              new DataOutputStream(chperm.getOutputStream());

            os.writeBytes("chmod 777 /dev/LZM_FJICC\n");

            os.flush();

            os.writeBytes("exit\n");

            os.flush();

              chperm.waitFor();

    } catch (IOException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    } catch (InterruptedException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

    }

 

问题四:S5VP210端口设置小结

//     定义用到的引脚   S5PV210_GPJ0(7)

//  设置引脚的输出

       s3c_gpio_cfgpin(S5PV210_GPJ0(7),S3C_GPIO_SFN(1));//设置为输出

       gpio_direction_output(S5PV210_GPJ0(7),0);

 

//释放总线

 #define OW_Pin S5PV210_GPJ0(7)

       s3c_gpio_cfgpin(OW_Pin,S3C_GPIO_SFN(0));//设置为输入

       s3c_gpio_setpull(OW_Pin,S3C_GPIO_PULL_UP);

gpio_get_value(OW_Pin)//获取引脚的输入电平状态

 

分享到:
评论

相关推荐

    JNI综合实验一:LED点亮+IO电平读取

    标题中的“JNI综合实验一:LED点亮+IO电平读取”是指一个关于Java Native Interface (JNI)的实践教程,该教程聚焦于如何利用JNI来控制硬件设备,具体包括LED灯的控制和输入/输出(I/O)电平的读取。在嵌入式系统或...

    JNI基础实验一:调用.so文件--友善之臂Tiny210 android 串口/pwm/ADC/LED

    在JNI中,我们需要创建C/C++函数,使用Linux的串口API(如open、write、read、close等)来打开、读写和关闭串口。然后在Java层通过JNI调用这些函数,实现Android应用与Tiny210串口的交互。 2. **PWM控制**:PWM是一...

    JNI调用驱动 打开LED灯

    在这个场景中,我们讨论的是如何通过JNI调用驱动程序来控制LED灯。 首先,我们需要理解Android系统的驱动模型。在Android中,驱动程序是操作系统内核的一部分,负责与硬件设备直接交互。这些驱动通常用C或C++编写,...

    JNI学习二:字符串参数传递与返回值

    JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码...这个示例中的"JNI学习二:字符串参数传递与返回值"就是一个很好的起点,通过实践可以深入理解JNI的工作原理和使用技巧。

    一个简单的JNI实验

    通过这个简单的JNI实验,你可以了解到如何在Java程序中嵌入本地代码,理解Java与本地代码之间的交互方式,为进一步深入学习和应用JNI打下基础。实践中遇到的问题和解决方法,都是学习过程中宝贵的实践经验。

    安卓串口Socket通讯USB驱动jni相关-Android通过jni控制LED灯.zip

    该压缩包文件“安卓串口Socket通讯USB驱动jni相关-Android通过jni控制LED灯.zip”主要涉及了在Android平台上利用JNI技术与硬件设备(如LED灯)进行通信的关键知识点。以下将详细介绍这些技术: 1. **JNI(Java ...

    android驱动JNI的USB2串口的参考实例

    在Android平台上,与硬件设备进行通信...通过学习和实践这个例子,开发者可以掌握如何在Android系统中使用JNI开发USB驱动,这对于那些需要与物理世界交互的应用程序,如工业自动化、物联网设备控制等,是非常有价值的。

    Android通过jni控制LED灯

    《Android通过JNI控制LED灯详解》 在移动设备开发领域,Android系统以其开源性和灵活性深受开发者喜爱。然而,当涉及到与硬件直接交互时,如控制LED灯这样的底层操作,Java层往往力有未逮。此时,JNI(Java Native ...

    android通过JNI访问硬件LED

    - **LED驱动程序**:这部分代码直接与硬件交互,可能包括初始化、设置状态和关闭LED等操作。它可能基于Linux设备驱动模型,利用系统提供的I/O接口。 5. **开发流程**: - 编写Java层的JNI接口,声明`native`方法...

    安卓串口Socket通讯USB驱动jni相关-Android中调用JNI例子.rar

    在Java层,可以调用JNI接口来控制USB设备,执行枚举设备、打开设备、发送/接收数据等操作。Android还需要在Manifest.xml中声明相应的USB权限。 5. **Android中调用JNI的例子**: 压缩包中的“Android中调用JNI例子...

    Android上层与驱动交互完整篇(APK->JNI->HAL->DRV)

    本文将详细阐述Android系统的这一核心功能,即如何从Apk(应用程序)通过JNI(Java Native Interface)到HAL(Hardware Abstraction Layer)再到DRV(驱动程序),实现上层应用对硬件资源的有效控制。 首先,我们从...

    使用JNI进行混合编程:在Java中调用C/C++本地库

    Java Native Interface(JNI)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景下非常有用,比如需要利用已有的C/C++库,或者提高程序的性能,因为本地代码通常可以更高效地执行...

    Android应用程序使用JNI调用驱动程序

    JNI允许Java应用程序与本地代码进行交互,包括操作系统内核、驱动程序等。本文将深入探讨如何利用Android NDK(Native Development Kit)在应用程序中使用JNI调用驱动程序。 首先,我们需要了解NDK的基本概念。NDK...

    rk3288 apk通过jni控制gpio

    在Android系统中,JNI(Java Native Interface)是Java与本地代码交互的重要桥梁,它允许Java应用程序调用C/C++编写的库。在这个“rk3288 apk通过jni控制gpio”的项目中,开发者利用JNI技术来操作Rockchip RK3288...

    jni.rar_JNI编程_java jni_jni_site:www.pudn.com

    JNI(Java Native Interface)是Java平台提供的一种标准接口,它允许Java代码和其他语言写的代码进行交互,特别是C和C++。JNI在很多场景下都扮演着重要的角色,比如提升性能、利用现有C/C++库、操作系统级别的交互等...

    android通过JNI控制LED

    在本文中,我们将深入探讨如何通过JNI在Android平台上控制硬件LED(Light Emitting Diode)。LED控制通常用于设备的状态指示或者实现特定的交互效果。 首先,我们需要了解JNI的基本概念。JNI提供了一个框架,使得...

    Android 串口 JNI 代码

    在Android中,串口通信主要用于与外部硬件设备交互,如传感器、嵌入式控制器等。 - **API限制**:Android原生SDK并不直接支持串口操作,开发者通常需要借助第三方库,如`Android-SerialPort-API`或者自定义JNI层来...

    jni开发demo:通过jni将一张彩色图片转换为黑白图片

    JNI(Java Native Interface)是Java平台提供的一种标准接口,它允许Java代码和其他语言写的代码进行交互。在Android系统中,JNI被广泛应用于性能优化、调用底层库、访问硬件设备等场景。本示例"jni开发demo:通过...

Global site tag (gtag.js) - Google Analytics