跟上篇同例,只是测试LED次设备号。

内核版本:android-kernel-2.6.36

android版本:2.3.4

目的:应用上布局4个按键,分别点亮LED1~4.

------------------------------------------------------------

驱动:

#include <linux/module.h>               /* For module specific items */#include <linux/moduleparam.h>          /* For new moduleparam's */#include <linux/types.h>                /* For standard types (like size_t) */#include <linux/errno.h>                /* For the -ENODEV/... values */#include <linux/kernel.h>               /* For printk/panic/... */#include <linux/fs.h>                   /* For file operations */#include <linux/ioport.h>               /* For io-port access */#include <linux/platform_device.h>      /* For platform_driver framework */#include <linux/init.h>                 /* For __init/__exit/... */#include <linux/uaccess.h>              /* For copy_to_user/put_user/... */#include <linux/io.h>                   /* For inb/outb/... */#include <linux/gpio.h>#include <linux/device.h>#include <linux/cdev.h>#include <linux/slab.h>               /*kmalloc */#define CMD_FLAG 'i'#define LED_ON _IOR(CMD_FLAG,0x00000000,__u32)#define LED_OFF _IOR(CMD_FLAG,0x00000001,__u32)//LED1 - LED4//gpk4 - gpk7static int major =0;static int minor =4;static struct class *led_class; struct cdev_led {struct cdev cdev;};static struct cdev_led *led_dev;//ioctlstatic int led_ioctl (struct file* filp,unsigned int cmd,unsigned long argv){printk(KERN_INFO "ioctl mode...\n");int minor = iminor(filp->f_path.dentry->d_inode);printk(KERN_INFO "minor :%d\n",minor);switch(cmd){case LED_ON:gpio_set_value(S3C64XX_GPK(minor+4),0);break;case LED_OFF:gpio_set_value(S3C64XX_GPK(minor+4),1);break;default:return -EINVAL;}return 0;}//openstatic int led_open(struct inode* i_node,struct file* filp){printk(KERN_INFO "open mode...\n");int err;int minor = iminor(i_node);printk(KERN_INFO "open minor : %d\n",minor);err = gpio_request(S3C64XX_GPK(minor+4),"myled");if(err<0){printk(KERN_INFO "gpio request faile\n");return err;}gpio_direction_output(S3C64XX_GPK(minor+4),1);return 0;}//closestatic void led_close(struct inode* i_node,struct file* filp){printk(KERN_INFO "close mode...\n");int minor = iminor(i_node);gpio_free(S3C64XX_GPK(minor+4));}// file operationsstatic struct file_operations fops={.owner = THIS_MODULE,.open  = led_open,.unlocked_ioctl = led_ioctl,.release = led_close};static void led_init_hw(struct cdev_led *dev,int minor){dev_t dev_no=MKDEV(major,minor); //根据主设备号和次设备号,获取设备节点。cdev_init( &dev->cdev,&fops);dev->cdev.owner = THIS_MODULE;int err = cdev_add(&dev->cdev,dev_no,1); //根据一个设备节点,加载一个设备。if(err)printk(KERN_INFO "error , add cdev\n");}static int __init led_init(void){dev_t dev_no;int result;result = alloc_chrdev_region(&dev_no,0,minor,"myled");  //动态创建字符设备节点,有4个次设备号,就分配4个。if(result < 0){printk(KERN_INFO "alloc dev_no faile\n");return result;}major = MAJOR(dev_no);led_dev = kmalloc(4*sizeof(struct cdev_led),GFP_KERNEL);if(!led_dev){result =-ENOMEM;goto faile_malloc;}memset(led_dev,0,4*(sizeof(struct cdev_led)));int i ;for(i=0;i<minor;i++){led_init_hw(&led_dev[i],i); //创建4个设备。}led_class = class_create(THIS_MODULE,"myled");for(i=0;i<minor;i++){device_create(led_class,NULL,MKDEV(major,i),NULL,"myled%d",i);}return 0;faile_malloc:return result;}static void __exit led_exit(void){dev_t dev_no = MKDEV(major,0);int i;for(i=0;i<minor;i++)cdev_del(&((led_dev+i)->cdev));unregister_chrdev_region(dev_no,4);kfree(led_dev);device_destroy(led_class,dev_no);class_destroy(led_class);}module_init(led_init);module_exit(led_exit);MODULE_AUTHOR("koliy <xxxx@163.com>");MODULE_DESCRIPTION("ARM test led minor");MODULE_LICENSE("GPL");

Makefile:

KERN_DIR = /android/linux-2.6.36-android   all:       make -C $(KERN_DIR) M=`pwd` modules   clean:       make -C $(KERN_DIR) M=`pwd` clean     obj-m   += android_led.o

================================================================

接下来布局好android的应用层按键,这里就简单贴上,主要是怎么调用JNI接口。

在这里说下,类名和JNI接口函数名称不要带'_'符号,因JNI会转换成' . ',造成java调用不到JNI接口。

package sz.ics.arm.test;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class Minor extends Activity implements OnClickListener {private Button bt_led1_on,bt_led1_off;private Button bt_led2_on,bt_led2_off;private Button bt_led3_on,bt_led3_off;private Button bt_led4_on,bt_led4_off;private Button bt_led_exit;private static final int LED_ON = 0;private static final int LED_OFF = 1;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        findID();        setOnclick();       // Minor_ledActivity p = new Minor_ledActivity();           }    private void findID()    {    bt_led1_on = (Button)findViewById(R.id.led1_on);    bt_led1_off = (Button)findViewById(R.id.led1_off);    bt_led2_on = (Button)findViewById(R.id.led2_on);    bt_led2_off = (Button)findViewById(R.id.led2_off);    bt_led3_on = (Button)findViewById(R.id.led3_on);    bt_led3_off = (Button)findViewById(R.id.led3_off);    bt_led4_on = (Button)findViewById(R.id.led4_on);    bt_led4_off = (Button)findViewById(R.id.led4_off);    bt_led_exit =(Button)findViewById(R.id.led_exit);    }    private void setOnclick()    {    bt_led1_on.setOnClickListener(this);    bt_led1_off.setOnClickListener(this);    bt_led2_on.setOnClickListener(this);    bt_led2_off.setOnClickListener(this);    bt_led3_on.setOnClickListener(this);    bt_led3_off.setOnClickListener(this);    bt_led4_on.setOnClickListener(this);    bt_led4_off.setOnClickListener(this);    bt_led_exit.setOnClickListener(this);    }@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtry{switch(v.getId()){case R.id.led1_on:{Minor p =new Minor();        int err = p.ledopen("/dev/myled0");        if(err < 0)        {        setTitle("don't open.");        finish();        }        setTitle("open");p.ledioctl(LED_ON);break;}case R.id.led1_off:{Minor p =new Minor();p.ledioctl(LED_OFF);p.ledclose("/dev/myled0");break;}case R.id.led2_on:{        int err = this.ledopen("/dev/myled1");        if(err < 0)        {        Toast.makeText(this, "error! don't load lib", Toast.LENGTH_LONG);        finish();        }this.ledioctl(LED_ON);break;}case R.id.led2_off:{this.ledioctl(LED_OFF);this.ledclose("/dev/myled1");break;}case R.id.led3_on:{        int err = this.ledopen("/dev/myled2");        if(err < 0)        {        Toast.makeText(this, "error! don't load lib", Toast.LENGTH_LONG);        finish();        }this.ledioctl(LED_ON);break;}case R.id.led3_off:{this.ledioctl(LED_OFF);this.ledclose("/dev/myled2");break;}case R.id.led4_on:{        int err = this.ledopen("/dev/myled3");        if(err < 0)        {        Toast.makeText(this, "error! don't load lib", Toast.LENGTH_LONG);        finish();        }this.ledioctl(LED_ON);break;}case R.id.led4_off:{this.ledioctl(LED_OFF);this.ledclose("/dev/myled3");break;}case R.id.led_exit:{finish();break;}default:{finish();return ;}}}catch(Exception e){e.printStackTrace();}}/* * load lib */static {try{System.loadLibrary("led");}catch(Exception e){e.printStackTrace();}}public  native int ledopen(String dev);public  native void ledclose(String dev);public  native int ledioctl(int cmd);}

JNI:对JNI方法不了解的请到我的第一篇去下载JNI学习资料。

/* * Copyright 2009 Cedric Priscal * * 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 <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <jni.h>#include <dirent.h>int fd =0;#define CMD_FLAG  'i'#define LED_ON_IOR(CMD_FLAG,0x00000000,__u32)#define LED_OFF_IOR(CMD_FLAG,0x00000001,__u32)#include "android/log.h"static const char *TAG="led-jni";#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)/* * Class:     minor_led * Method:    led_open* Signature: ([java/lang/string)I */JNIEXPORT jint JNICALL  Java_sz_ics_arm_test_Minor_ledopen(JNIEnv*env,jobject obj,jstring dev){LOGI("entry open---> ");char dev_name[128];int len=(*env)->GetStringLength(env,dev);(*env)->GetStringUTFRegion(env,dev,0,len,dev_name); //不涉及内存操作LOGI("%s\n",dev_name);dev_name[len]='\0';fd = open(dev_name,O_RDWR);if(fd<0){LOGI("Don't open %s\n",dev_name);return -1;}return 0;}/** Class minor_led* Method: led_close* Signature: ([java/lang/string)V*/JNIEXPORT void JNICALLJava_sz_ics_arm_test_Minor_ledclose(JNIEnv*env,jobject obj,jstring dev){LOGI("entry close---> ");const char * dev_name;dev_name =(*env)->GetStringUTFChars(env,dev,NULL); //涉及内存操作,需另外malloc、strcpy之后,再操作返回值,耗时费力if(dev_name == NULL){LOGI("Don't get %s\n",dev_name);return;}LOGI(" get %s\n",dev_name);(*env)->ReleaseStringUTFChars(env,dev,dev_name);close(fd);}/** Class minor_led* Method: led_ioctl* Signature: (I)I*/JNIEXPORT jint JNICALLJava_sz_ics_arm_test_Minor_ledioctl(JNIEnv* env,jobject obj,jint cmd){LOGI("entry ioctl---> ");if(cmd>0)ioctl(fd,LED_OFF,NULL);elseioctl(fd,LED_ON,NULL);return 0;}

上文提到,生成libxx.so通过NDK工具来生成,所以编写
Android.mk 文件

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)TARGET_PLATFORM := android-3LOCAL_MODULE    := ledLOCAL_SRC_FILES := led.cLOCAL_LDLIBS    := -lloginclude $(BUILD_SHARED_LIBRARY)

最后把应用工程包放进NDK里编译,具体步骤看上篇博文。

更多相关文章

  1. android 命令(adb shell)进入指定模拟器或设备
  2. 检测Android设备有线网络连接状态
  3. 如何取Android设备日志
  4. Android os设备谎言分辨率的解决方案
  5. Android Http通信(使用 标准Java接口)及解析Json
  6. Android TimeLine 时间节点轴的实现

随机推荐

  1. Android的View的VISIBLE,INVISIBLE,GONE
  2. Android(安卓)可拖拽悬浮按钮
  3. 使用showmap分析android进程内存占用情况
  4. 详解Android中的屏幕方向类型
  5. 纯css3无js实现的Android(安卓)Logo(有简
  6. 百度地图应用开发(一)
  7. 在Titanium中使用Android的Service
  8. 下载安装eclipse ADT插件:
  9. ClassNotFoundException解决方案总结
  10. Android设置透明状态栏,仿ios状态栏