以LED灯为例,演示ndk,贴出代码:
LedDevice.java代码:
package com.android.emobile;
import android.util.Log;
public class LedDevice {
static {
try {
Log.i("JNI", "Trying to load libled.so");
System.loadLibrary("ledsctrl_jni");
}
catch (UnsatisfiedLinkError ule) {
Log.e("JNI", "WARNING: Could not load libled.so");
}}
private static final String TAG = "LedDevice";
private static int ledState;
public static final int LED_ON = 1;
public static final int LED_OFF = 0;
LedDevice() {
ledState = LED_OFF;
}
public int open() {
Log.d(TAG,"Here:java framework Call:JNI native function");
return opendevice();
}
public int close() {
Log.d(TAG,"Here:java framework Call:JNI native function");
return closedevice();
}
public int get_state(int num,int flag) {
if (flag == 1)
{
Log.d(TAG,"Here:java framework Call:JNI native function");
return (getstate(num) == LED_ON) ? LED_ON : LED_OFF;
}
else
return ledState;
}
public int switch_on_off(int num, int on_off) {
Log.d(TAG,"Here:java framework Call:JNI native function");
if (switchonoff(num, on_off) >= 0)
{
ledState = on_off;
return 0;
}
else
return -1;
}
/* */
public static native int opendevice();
/* */
public static native int closedevice();
/* */
public static native int switchonoff(int num ,int on_off);
/* */
public static native int getstate(int num);
}
LedsCtrl.java代码:
package com.android.emobile;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class LedsCtrl extends Activity implements OnClickListener{
private static final String TAG = "LedsCtrl";
LedDevice mLedDevice;
Button mButtonLedall;
Button mButtonLedallState;
TextView mtextview;
private static int state=1,flag=1;
private static int ledState=0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButtonLedall = (Button) findViewById(R.id.buttonTurnOnLed2);
mButtonLedall.setOnClickListener(this);
mButtonLedallState = (Button) findViewById(R.id.buttonStateOfLed2);
mButtonLedallState.setOnClickListener(this);
mtextview=(TextView) findViewById(R.id.text_view);
mLedDevice = new LedDevice();
Log.d(TAG,"Open The mLedDevice");
if (mLedDevice.open() != 0)
Log.d(TAG,"mLedDevice open failed!");
}
public void onDestroy() {
super.onDestroy();
mLedDevice.close();
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.buttonTurnOnLed2:
Log.d(TAG,"Turn On Led2");
if(flag==1)
{
mLedDevice.switch_on_off(1,0);
mLedDevice.switch_on_off(2,0);
mLedDevice.switch_on_off(3,0);
mLedDevice.switch_on_off(4,0);
flag=2;
}
if(state<5)
{
if(state!=1)
mLedDevice.switch_on_off(state-1,0);
mLedDevice.switch_on_off(state,1);
}
else if(state==5)
{
mLedDevice.switch_on_off(state-1,0);
}
state++;
if(state==6)
state=1;
mtextview.setText("???");
break;
case R.id.buttonStateOfLed2:
Log.d(TAG,"Get Led4 State");
int i;
for(i=1;i<5;i++)
{
ledState=mLedDevice.get_state(i,1);
if(ledState==0)
continue;
else
break;
}
if(i<5)
mtextview.setText("第"+String.valueOf(i)+"个灯亮");
else
mtextview.setText("全灭!!!");
break;
}
}
}
Led驱动程序
/******************************************************
*Project description:测试开发板上的LED灯
*Time:2011-12-12
*Author:Embest <lutao@embedinfo.com>
*******************************************************/
/*头文件*/
#include<linux/init.h>
#include<linux/module.h>
#include<linux/sched.h>
#include<linux/kernel.h>
#include <asm/uaccess.h>
#include <plat/gpio-cfg.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
/*定义设备目录*/
#define DEVICE_LIST "led_test"
/*定义设备文件节点*/
#define DEVICE_NODE "led_light"
#define LED1 0x01
#define LED2 0x02
#define LED3 0x04
#define LED4 0x08
/*定义申请设备号(主设备号+次设备号)的变量*/
static dev_t num_dev;
/*字符设备的变量定义*/
static struct cdev *cdev_p;
/*定义一个class类*/
static struct class *led_dev_class;
/*定义一个全局变量,表示LED灯的状态*/
static unsigned char led_status = 0;
/*设置LED灯的状态*/
static void set_led_status(unsigned char status)
{
/*表示LED灯的状态是否发生变化*/
unsigned char led_status_changed;
led_status_changed= led_status^(status & 0xF);
/*数据变化检测*/
led_status=(status & 0xF);
/*如果4个LED灯的状态发生了变化*/
if(led_status_changed!=0x00)
{
/*判断是否改变LED1灯的状态*/
if(led_status_changed&LED1)
{
if(led_status&LED1)
gpio_direction_output(S5PV210_GPH0(0),0);
else
gpio_direction_output(S5PV210_GPH0(0),1);
}
/*判断是否改变LED2灯的状态*/
if(led_status_changed&LED2)
{
if(led_status&LED2)
gpio_direction_output(S5PV210_GPH0(1),0);
else
gpio_direction_output(S5PV210_GPH0(1),1);
}
/*判断是否改变LED3灯的状态*/
if(led_status_changed&LED3)
{
if(led_status&LED3)
gpio_direction_output(S5PV210_GPH0(2),0);
else
gpio_direction_output(S5PV210_GPH0(2),1);
}
/*判断是否改变LED4灯的状态*/
if(led_status_changed&LED4)
{
if(led_status&LED4)
gpio_direction_output(S5PV210_GPH0(3),0);
else
gpio_direction_output(S5PV210_GPH0(3),1);
}
}
}
/*读取LED灯的状态*/
static ssize_t s5pv210_led_read(struct file * file,char * buf,size_t count,loff_t * f_ops)
{
/*从用户空间读取数据,获取LED灯的状态*/
copy_to_user(buf, (char *)&led_status, sizeof(unsigned char));
return sizeof(unsigned char);
}
/*定义实现LED灯的写操作*/
static ssize_t s5pv210_led_write (struct file * file,const char * buf, size_t count,loff_t * f_ops)
{
unsigned char status;
if(count==1)
{
/*向用户空间写数据,如果写失败,则返回错误*/
if(copy_from_user(&status, buf,sizeof(unsigned char)))
return -EFAULT;
set_led_status(status);
return sizeof(unsigned char);
}else
return -EFAULT;
}
/*打开LED设备*/
static ssize_t s5pv210_led_open(struct inode * inode,struct file * file)
{ /*增加管理此设备的 owner模块的使用计数*/
try_module_get(THIS_MODULE);
return 0;
}
/*释放LED设备*/
static ssize_t s5pv210_led_release(struct inode * inode, struct file * file)
{
/*减少管理此设备的 owner模块的使用计数*/
module_put(THIS_MODULE);
return 0;
}
/*定义具体的文件操作*/
static const struct file_operations s5pv210_led_ctrl_ops={
.owner = THIS_MODULE,
.open = s5pv210_led_open,
.read = s5pv210_led_read,
.write = s5pv210_led_write,
.release = s5pv210_led_release,
};
/*LED灯的初始化和LED设备驱动的加载*/
static int s5pv210_led_ctrl_init(void)
{
int err;
struct device* temp=NULL;
unsigned int gpio;
/*GPIO口的初始化LED1,LED2,LED3,LED4,设置为输出*/
for(gpio=S5PV210_GPH0(0);gpio<S5PV210_GPH0(4);gpio++)
{
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(1));
}
/*动态注册led_test设备,num_dev为动态分配出来的设备号(主设备号+次设备号)*/
err=alloc_chrdev_region(&num_dev,0,1,DEVICE_LIST);
if (err < 0) {
printk(KERN_ERR "LED: unable to get device name %d/n", err);
return err;
}
/*动态分配cdev内存空间*/
cdev_p = cdev_alloc();
cdev_p->ops = &s5pv210_led_ctrl_ops;
/*加载设备驱动*/
err=cdev_add(cdev_p,num_dev,1);
if(err){
printk(KERN_ERR "LED: unable to add the device %d/n", err);
return err;
}
/*在/sys/class下创建led_test目录*/
led_dev_class=class_create(THIS_MODULE,DEVICE_LIST);
if(IS_ERR(led_dev_class))
{
err=PTR_ERR(led_dev_class);
goto unregister_cdev;
}
/*基于/sys/class/led_test和/dev下面创建led_light设备文件*/
temp=device_create(led_dev_class, NULL,num_dev, NULL, DEVICE_NODE);
if(IS_ERR(temp))
{
err=PTR_ERR(temp);
goto unregister_class;
}
return 0;
unregister_class:
class_destroy(led_dev_class);
unregister_cdev:
cdev_del(cdev_p);
return err;
}
/*模块的初始化*/
static int __init s5pv210_led_init(void)
{
int ret;
ret = s5pv210_led_ctrl_init();
if(ret)
{
printk(KERN_ERR "Apply: S5PV210_LED_init--Fail !!!/n");
return ret;
}
return 0;
}
/*模块的退出*/
static void __exit s5pv210_led_exit(void)
{
device_destroy(led_dev_class,DEVICE_NODE);
class_destroy(led_dev_class);
cdev_del(cdev_p);
unregister_chrdev_region(num_dev,1);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LED driver test");
module_init(s5pv210_led_init);
module_exit(s5pv210_led_exit);