跟上篇同例,只是测试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. framebuffer (2)
  2. Android(安卓)手机上获取物理唯一标识码
  3. android 深度搜索笔记一
  4. Android(安卓)蓝牙开发浅析
  5. Android(安卓)android:allowBackup waiting for backup
  6. struts2中获取request、response,与android客户端进行交互
  7. 2011年Android(安卓)Camera学习笔记之一
  8. Android(安卓)N 指纹框架
  9. Android获取设备唯一标识完美解决方案

随机推荐

  1. Android(安卓)解决WebView无法上传文件的
  2. UI开发第一篇——android的九宫格式实现
  3. Android(安卓)调试工具集合
  4. Android(安卓)架构解析及驱动 键盘篇
  5. android 动画学习系列(一)
  6. ACTION_PICK与ACTION_GET_CONTENT
  7. android控件之GridView
  8. Android热插拔事件处理流程--Vold
  9. android包Android(安卓)"java.lang.NoCla
  10. Android动态显示和隐藏状态栏探究。