1 、电脑环境
ADT
NDK
JDK
2、android开发板
处理器:s5pv210
控制的外围电路为4个led,附上led电路图:
3、创建操作led的jni程序
1.在adt中创建一个android工程
2.在该工程的src目录中创建一个名为com.jni.led的包
3.在这个包下创建一个名为LedControl的类
内容如下:
public class LedControl {
public native int led_init();
public native int ioctl(int ledID, int ledState);
public native int close();
static{
System.loadLibrary("led-jni");/*加载JNI库*/
}
}
4.打开控制端,进入该工程的src目录,使用命令:javah -jni com.jni.led.LedControl
生成com_jni_led_LedControl.h头文件,内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jni_led_LedControl */
#ifndef _Included_com_jni_led_LedControl
#define _Included_com_jni_led_LedControl
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jni_led_LedControl
* Method: led_init
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jni_led_LedControl_led_1init
(JNIEnv *, jobject);
/*
* Class: com_jni_led_LedControl
* Method: ioctl
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_jni_led_LedControl_ioctl
(JNIEnv *, jobject, jint, jint);
/*
* Class: com_jni_led_LedControl
* Method: close
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jni_led_LedControl_close
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
5.根据上面这个头文件,创建led.c文件
在该android工程顶层目录创建jni文件夹,并在该文件夹创建led.c和Android.mk
内容分别如下:
led.c
#include <stdio.h>
#include <string.h>
#include <jni.h>
#include <fcntl.h>
#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/leds" //device point
#define LED_ON 1
#define LED_OFF 0
int fd;
/*
* Class: com_jni_led_LedControl
* Method: led_init
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jni_led_LedControl_led_1init
(JNIEnv *env, jobject obj)
{
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;
}
/*
* Class: com_jni_led_LedControl
* Method: ioctl
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_jni_led_LedControl_ioctl
(JNIEnv *env, jobject obj, jint ledId, jint ledState)
{
LOGE("IOCTL()-> %d ledState \n",ledState);
LOGE("IOCTL()-> %d ledState \n",0);
ioctl(fd,ledState, ledId);
return 1;
}
/*
* Class: com_jni_led_LedControl
* Method: close
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jni_led_LedControl_close
(JNIEnv *env, jobject obj)
{
close(fd);
return 1;
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := led-jni
LOCAL_SRC_FILES := led.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
6.编译led.c
在终端进入该android目录的jni目录,执行命令E:\andriod\ndk\android-ndk-r9\ndk-build(这个根据个人ndk目录而修改)完成后生成obj目录,该目录保护编译后的库(libjni-led.so),将该目录下的目录一起拷贝到libs目录
7.调用该库,源码如下:
package com.example.led_jni;
import com.jni.led.LedControl;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private Button led1,led2,led3,led4;
private LedControl myled;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
led1 = (Button) findViewById(R.id.led1);
led2 = (Button) findViewById(R.id.led2);
led3 = (Button) findViewById(R.id.led3);
led4 = (Button) findViewById(R.id.led4);
led1.setOnClickListener(this);
led2.setOnClickListener(this);
led3.setOnClickListener(this);
led4.setOnClickListener(this);
myled = new LedControl();
myled.led_init();
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()) {
case R.id.led1:
myled.ioctl(0, 1);
break;
case R.id.led2:
myled.ioctl(1, 1);
break;
case R.id.led3:
myled.ioctl(2, 0);
break;
case R.id.led4:
myled.ioctl(3, 1);
break;
}
}
}
只是测试,只打开了led灯,没有写关闭的
8.linux驱动程序操作led片段,如下:
static long s5pv210_leds_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
switch(cmd) {
case 0:
if (arg > LED_NUM) {
return -EINVAL;
}
gpio_set_value(led_gpios[arg], cmd);
printk(DEVICE_NAME": %ld %d\n", arg, cmd);
case 1:
if (arg > LED_NUM) {
return -EINVAL;
}
gpio_set_value(led_gpios[arg], !cmd);
printk(DEVICE_NAME": %ld %d\n", arg, cmd);
break;
default:
return -EINVAL;
}
return 0;
}
使用之前需要修改驱动接点权限
使用命令:chmod777 /dev/leds
4、附驱动源码和工程源码
1.led驱动
2.android控制led工程