简单字符设备驱动——LED驱动

驱动程序ledkey_drv.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>
#include <linux/delay.h>

#define DEVICE_NAME	"ledkey"
#define LEDKEY_MAJOR  241    /*棰勮鐨刟dc鐨勪富璁惧鍙?/ 

static int  ledkey_MAJOR=LEDKEY_MAJOR;  

#define Led_ON 1
#define Led_OFF  0

static struct cdev cdev_ledkey;
struct class *ledkey_class;

static long s3c6410_ledkey_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{  
  	unsigned char k;
	switch(cmd) 
    	{
      	case 0:
		  		gpio_set_value(S3C64XX_GPP(0),0);
				k=gpio_get_value(S3C64XX_GPP(0));
				printk("<0>\n Led is OFF,GPP0= %d\n",k);
				break;
      	case 1:
		  		gpio_set_value(S3C64XX_GPP(0),1);
				k=gpio_get_value(S3C64XX_GPP(0));
				printk("<0>\n Led is ON,GPP0= %d\n",k);
				break;		
      	default:
	  			printk("fail\n");
				printk("<0>\n please enter the cmd again!\n");
        			return -EINVAL;
    	}
}

static int s3c6410_ledkey_open(struct inode *inode, struct file *filp)
{
	s3c_gpio_cfgpin(S3C64XX_GPP(0), 0x01);  /*閰嶇疆寮曡剼GPP0锛岃緭鍑烘柟寮?姝や负杈撳嚭*/
//	printk("<0>閰嶇疆寮曡剼GPP0涓鸿緭鍑?\n");
	return 0;
}

static struct file_operations s3c6410_ledkey_fops = 
{
	.owner		=	THIS_MODULE,
	.unlocked_ioctl	=	s3c6410_ledkey_ioctl,
	.open		=	s3c6410_ledkey_open,
};

static int __init s3c6410_ledkey_init(void)
{
	int result;
	dev_t devno = MKDEV(ledkey_MAJOR,0);

//	result = register_chrdev_region(devno,1,DEVICE_NAME); /* 闈欐€佺敵璇疯澶囧彿 */
	result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME); /* 鍔ㄦ€佺敵璇疯澶囧彿 */
	ledkey_MAJOR=MAJOR(devno);
	if(result)
	{
		printk(KERN_NOTICE "Error %d register ledkey",result);
		return result;
	}

    
 	cdev_init(&cdev_ledkey,&s3c6410_ledkey_fops);  /*鍒濆鍖栧苟娉ㄥ唽cdev*/  
	result = cdev_add(&cdev_ledkey,devno,1);
	if(result)
	{
		printk(KERN_NOTICE "Error %d adding ledkey",result);
		return result;
	}

	ledkey_class = class_create(THIS_MODULE, "ledkey_class");   /*鍦╯ys涓嬪垱寤虹被鐩綍/sys/class/ledkey_class*/  
	device_create(ledkey_class, NULL, MKDEV(ledkey_MAJOR,0), "NULL","ledkey");   /*鑷姩鍒涘缓璁惧鏂囦欢*/ 

	return 0;	
}

static void __exit s3c6410_ledkey_exit(void)
{
	cdev_del(&cdev_ledkey);   /*娉ㄩ攢cdev*/  
	unregister_chrdev_region(MKDEV(ledkey_MAJOR,0),1);   /*閲婃斁璁惧鍙?/  
	device_destroy(ledkey_class,MKDEV(ledkey_MAJOR,0));  
	class_destroy(ledkey_class);  
}


module_init(s3c6410_ledkey_init);
module_exit(s3c6410_ledkey_exit);

MODULE_LICENSE("GPL");


测试程序ledkey_test.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>

#define Led_ON   1
#define Led_OFF  0

static int fd;

int main(int argc, char *argv[])
{  
	fd = open("/dev/ledkey", 0);
    	if (fd < 0)
    	{
     		perror("Failed to open ledkey");
      		exit(1);
    	}
	printf("opend ledkey success!\n");
	
	if(strcmp("Led_ON", argv[1])==0)
	{
		printf("Led is ON!\n");
		ioctl(fd, Led_ON);	
	}
	else if(strcmp("Led_OFF", argv[1])==0)
	{


		printf("Led is OFF!\n");
		ioctl(fd, Led_OFF);
	}
	else 
	{
		printf("please input Led_ON or Led_OFF!\n");
	}
    	close(fd);
    	return 0;
}


Makefile

ifneq ($(KERNELRELEASE),)  
 
obj-m := ledkey_drv.o  
  
else  
  
KDIR := /home/ok6410/linux3.0.1/linux-3.0.1
  
all:  
	make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux-  
clean:  
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers  
  
endif  


 

你可能感兴趣的:(简单字符设备驱动——LED驱动)