`
koliy
  • 浏览: 149004 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

android驱动学习-led次设备号(2)

阅读更多

 跟上篇同例,只是测试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 - gpk7
static int major =0;
static int minor =4;
static struct class *led_class;

 struct cdev_led {
	struct cdev cdev;
};

static struct cdev_led *led_dev;

//ioctl
static 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;
}
//open
static 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;
}
//close
static 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 operations
static 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);
    }
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		try{
			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 JNICALL
Java_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 JNICALL
Java_sz_ics_arm_test_Minor_ledioctl(JNIEnv* env,jobject obj,jint cmd)
{
	LOGI("entry ioctl---> ");
	if(cmd>0)
		ioctl(fd,LED_OFF,NULL);
	else
		ioctl(fd,LED_ON,NULL);
	return 0;
}

 

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

 

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

TARGET_PLATFORM := android-3
LOCAL_MODULE    := led
LOCAL_SRC_FILES := led.c
LOCAL_LDLIBS    := -llog

include $(BUILD_SHARED_LIBRARY)

 

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

分享到:
评论

相关推荐

    android驱动学习---led实验

    总的来说,"android驱动学习---led实验"涵盖了Android驱动开发的基础知识,包括Linux驱动模型、设备注册与卸载、I/O操作,以及JNI在驱动与应用间的通信。通过这个实验,开发者可以深入理解Android系统的底层工作原理...

    Android内核led灯驱动程序

    在Android系统中,LED灯驱动程序是内核层面的一个重要组成部分,它负责与硬件交互,控制设备上的LED灯的亮灭状态。LED灯驱动通常基于Linux内核的设备驱动模型来编写,允许操作系统通过特定的接口与硬件进行通信。在...

    Android-jni-test for smart210-led

    这个"Android-jni-test for smart210-led"项目是关于如何利用JNI来调用Linux内核驱动,以便控制特定硬件设备——友善科技的SMART210板子上的LED灯。下面将详细介绍这个项目的相关知识点。 1. **JNI基础**: JNI是...

    Android驱动 Led灯源代码

    自己动手写最简单的Android驱动---LED驱动的编写 技术博客地址: http://blog.csdn.net/k_linux_man/article/details/7023824 Andoird驱动编写。编写Android驱动入门资料

    smart210-android-led

    标题“smart210-android-led”暗示我们正在讨论一个针对Smart210开发板的Android系统中的LED驱动程序。Smart210是一款基于ARM Cortex-A8处理器的开发平台,常用于嵌入式设备和物联网应用的开发。在这个项目中,...

    Android内核和驱动篇-Android内核介绍

    2. Android 电源管理(PM):一个基于标准 Linux 电源管理系统的轻量级的 Android 电源管理驱动,针对嵌入式设备做了很多优化。源代码位于 kernel/power/earlysuspend.c、kernel/power/consoleearlysuspend.c、...

    test-led.zip_android_android 控制闪光灯_android 驱动_android ,项目_测试

    在Android系统中,控制设备硬件如LED(Light Emitting Diode,发光二极管)的闪光灯是一项常见的功能,尤其在拍照、手电筒应用等场景中不可或缺。本项目"test-led.zip"专注于在Android平台上实现对闪光灯的底层驱动...

    Android驱动例子(LED灯控制).pdf

    总结起来,这个例子旨在指导初学者理解Android驱动开发的基本流程,从硬件原理到驱动编写,再到应用程序调用,覆盖了完整的驱动开发过程。通过实际操作,开发者可以更好地掌握驱动与应用之间的交互机制,为后续的...

    android驱动例子(LED灯控制)

    在驱动程序中,需要定义主设备号和次设备号来标识设备。例如: ```c #define VIB_MAJOR 97 // 主设备号 #define SCULL_NR_DEVS 4 #define SCULL_QUANTUM 4000 #define SCULL_QSET 1000 // 其他定义 ``` 5....

    Android内核和驱动篇-Android内核介绍[归纳].pdf

    2. Android 电源管理(PM):一个基于标准 Linux 电源管理系统的轻量级的 Android 电源管理驱动,针对嵌入式设备做了很多优化。源代码位于 kernel/power/earlysuspend.c kernel/power/consoleearlysuspend.c kernel/...

    android通过JNI访问硬件LED

    - 不同Android设备的硬件接口可能不同,因此驱动程序可能需要针对具体设备进行调整。 - 调试JNI代码通常较为困难,因为需要在设备或模拟器上运行,并可能涉及系统日志(Logcat)和调试器(如NDK-GDB)的使用。 - ...

    android5.1 led驱动 到apk一体化接口

    在Android 5.1版本中,通过在框架服务层添加LED驱动相关的JNI接口和AIDL接口,使得LED驱动与APK层可以通过Android系统服务进行通信,实现了LED驱动的软硬件解耦和平台无关性,能够使开发者在APK层控制LED设备。...

    android led 测试例子

    在Android系统中,LED(Light Emitting Diode)驱动是一个重要的组成部分,它允许设备上的LED灯进行各种功能,如通知灯、电量指示灯等。这篇文档是台湾一家公司提供的开放培训资料,专注于讲解如何在Android平台上...

    leds.zip_android_android底层_eclipse android_eclipse led_led驱动

    在描述中提到,“基于eclipse-Java写的led驱动,运行在android系统上”,这表明开发者使用Java语言,并在Eclipse环境中编写了一个用于控制Android设备LED灯的驱动程序。Android系统允许开发者通过Java API来访问硬件...

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

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

    android-framework-hal

    - **驱动程序的集成**:讨论如何将自定义的驱动程序集成到Android框架中。 #### 9.2 撰写Anroid应用程式以控制LED - **控制LED的应用程序**:通过编写一个简单的应用程序来控制LED灯。 #### 9.3 标准的Android ...

    Android驱动例子(LED灯控制)

    本例子,讲述在Android2.1上完全自已开发一个驱动去控制硬件口并写应用测试该驱动,通过这样一个例子,解析android下的驱动开发流程的...要达到的效果:通过Android的应用,调用驱动程序,在开发板上控制4个LED的亮灭。

    s5pc100-led驱动源码

    2. GPIO与LED驱动 在S5PC100中,LED通常被配置为GPIO输出,通过设置GPIO引脚的电平高低来控制LED的亮灭。LED驱动源码的主要任务就是管理和操作这些GPIO引脚。驱动程序会包含初始化、打开、关闭、亮度设置等函数,...

Global site tag (gtag.js) - Google Analytics