用ioctl传入命令控制LED(需要自己建立节点)

驱动程序

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <asm/io.h>  //ioremap()

/* 定义幻数 */
#define MEMDEV_IOC_MAGIC  'k'

/* 定义命令 */
#define LED_ON_1  _IOR(MEMDEV_IOC_MAGIC,1,int)   //读
#define LED_ON_2  _IOR(MEMDEV_IOC_MAGIC,2,int)

#define LED_ON_3  _IOW(MEMDEV_IOC_MAGIC,3,int)	 //写
#define LED_ON_4  _IOW(MEMDEV_IOC_MAGIC,4,int)

#define MEMDEV_IOC_MAXNR 4

volatile unsigned long *gpbcon = (void *)0;   //LED
volatile unsigned long *gpbdat = (void *)0;

//////////////////////////////////////////////////////////////////

/*IO操作*/
int ioctl_led_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
    int ret = 0;
    int ioarg = 0;
  
    /* 根据命令,执行相应的操作 */
    switch(cmd) {
	    	
	      case LED_ON_1:
		      	printk("The CMD LED_ON_1  ---===>>>\n");
		      	ret = __get_user(ioarg, (int *)arg);
		      	if(ioarg == 0x01)
		      	{
		      		*gpbdat &= ~(1<<5);
		      		printk("you input CMD that Light the LED \n");
		      	}
		      	else if(ioarg == 0x81)
		      	{
		      		*gpbdat |= (1<<5);
		      		printk("you input CMD that UNlight the LED \n");	
		      	}
		      	else
		      	{
		      		printk("Wrong CMD \n");
		      	}
	        break;
	      
	
	      case LED_ON_2: 
		      	printk("The CMD LED_ON_2   ---===>>>  \n");
		        ret = __get_user(ioarg, (int *)arg);     
		        if(ioarg == 0x02)
		      	{
		      		*gpbdat &= ~(1<<6);
		      		printk("you input CMD that Light the LED \n");
		      	}
		      	else if(ioarg == 0x82)
		      	{
		      		*gpbdat |= (1<<6);
		      		printk("you input CMD that UNlight the LED \n");	
		      	}
		      	else
		      	{
		      		printk("Wrong CMD \n");
		      	}
	        break;
	      
	  
	      case LED_ON_3: 
		        printk("The CMD LED_ON_4  \n");
		      	printk("The third LED on !!! output the number 666 !!!\n");
		      	ioarg = 666;
		        ret = __put_user(ioarg, (int *)arg);
		        *gpbdat &= ~(1<<7);
	        break;
	     
	     
	      case LED_ON_4:
		        printk("The CMD LED_ON_4  \n");
		      	printk("The forth LED on !!! output the number 888 !!!\n");
		      	ioarg = 888;
		      	ret = __put_user(ioarg, (int *)arg);
		      	*gpbdat &= ~(1<<8);
	      	break;
	
	      default:  
	       		 return -EINVAL;
    }
    return ret;

}


static int ioctl_led_open(struct inode *inode, struct file *file)
{		
	*gpbdat |= ((1<<5) | (1<<6) | (1<<7) | (1<<8));  //LED全灭
	return 0;
}


static struct file_operations led_fops = {
    .owner   =  THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open    =  ioctl_led_open,     	
    .ioctl   =  ioctl_led_ioctl,   
};

int major;   //主设备号

static int ioctl_led_init(void)
{
	major = register_chrdev(0, "myled", &led_fops);
	gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
	gpbdat = gpbcon + 1;
	return 0;
}

static void ioctl_led_exit(void)
{
	unregister_chrdev(major, "myled");
	iounmap(gpbcon);
}


module_init(ioctl_led_init);
module_exit(ioctl_led_exit);
MODULE_LICENSE("GPL");

测试程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <linux/ioctl.h>


/* 定义幻数 */
#define MEMDEV_IOC_MAGIC  'k'

/* 定义命令 */
#define LED_ON_1  _IOR(MEMDEV_IOC_MAGIC,1,int)   //读
#define LED_ON_2  _IOR(MEMDEV_IOC_MAGIC,2,int)

#define LED_ON_3  _IOW(MEMDEV_IOC_MAGIC,3,int)	 //写
#define LED_ON_4  _IOW(MEMDEV_IOC_MAGIC,4,int)

#define MEMDEV_IOC_MAXNR 4

static int input[4] = {{"cmd1"},{"cmd2"},{"cmd3"},{"cmd4"}};

int main(int argc,char **argv)
{
	int fd = 0;
	int cmd;
	int input_flag = 0;
	int arg = 0;
	unsigned char key_val;
		
	/*打开设备文件*/
	fd = open("/dev/ioctlled",O_RDWR);   //ioctlled  在  /dev/  下可以看见是这个名字
	if (fd < 0)
	{
		printf("Open Dev Mem0 Error!\n");
		return -1;
	}
	
	//while(1)
	//{	
		if (strcmp(*input, argv[1]) == 0)
		{
			input_flag = 1;		
		}
		else if (strcmp(*(input+1), argv[1]) == 0)
		{
			input_flag = 2;	
		}
		else if (strcmp(*(input+2), argv[1]) == 0)
		{
			input_flag = 3;	
		}
		else if (strcmp(*(input+3), argv[1]) == 0)
		{
			input_flag = 4;		
		}
		else
		{
			printf("Wrong CMD ---===>>>  \n");	
		}
		
		
		switch(input_flag)
		{
			
			case 0x01:    //judge the "input_flag"
			cmd = LED_ON_1;
			arg = 0x01;   //write "arg" to driver 
			if (ioctl(fd, cmd, &arg) < 0)
		        {
		        	printf("Call cmd MEMDEV_IOCPRINT fail\n");
		        	return -1;
			}
			break;
	
			case 0x02:
			cmd = LED_ON_2;
			arg = 0x02;
			if (ioctl(fd, cmd, &arg) < 0)
		        {
		        	printf("Call cmd MEMDEV_IOCSETDATA fail\n");
		        	return -1;
			}
			break;
			
			case 0x03:
			cmd = LED_ON_3;
			if (ioctl(fd, cmd, &arg) < 0)
		        {
		        	printf("Call cmd MEMDEV_IOCGETDATA fail\n");
		        	return -1;
			}
			printf("we received number %d from kernel \n",arg);
			break;
		
			case 0x04:
			cmd = LED_ON_4;
			if (ioctl(fd, cmd, &arg) < 0)
		        {
		        	printf("Call cmd MEMDEV_IOCGETDATA fail\n");
		        	return -1;
			}
			printf("we received number %d from kernel \n",arg);
			break;		
		}
	//}
	
	close(fd);
	return 0;	
}

运行结果

[root@EmbedSky huayang]# insmod ioctlled.ko                                     
Loaded Modle        这是打印出的一句话                                                           
[root@EmbedSky huayang]#


[root@EmbedSky huayang]# cat /proc/devices                                      
Character devices:                                                              
  1 mem                                                                         
  4 /dev/vc/0                                                                   
  4 tty                                                                         
  5 /dev/tty                                                                    
  5 /dev/console                                                                
  5 /dev/ptmx                                                                   
  7 vcs                                                                         
 10 misc                                                                        
 13 input                                                                       
 14 sound                                                                       
 29 fb                                                                          
 81 video4linux                                                                 
 89 i2c                                                                         
 90 mtd                                                                         
116 alsa                                                                        
128 ptm                                                                         
136 pts                                                                         
180 usb                                                                         
188 ttyUSB                                                                      
189 usb_device                                                                  
204 tq2440_serial                                                               

252 myled             这是我们安装的模块 它的主设备号是252                                                         

253 usb_endpoint                                                                
254 rtc 

创建设备节点并查看一下

[root@EmbedSky huayang]# mknod /dev/ioctlled c 252 0                               
[root@EmbedSky huayang]# ls /dev/ioctlled                                          
/dev/ioctlled                                                                      
[root@EmbedSky huayang]# 


测试它

[root@EmbedSky huayang]# ioctlledtest cmd1                                      
The CMD LED_ON_1  ---===>>>                                                     
you input CMD that Light the LED      这是打印出的信息                                         
[root@EmbedSky huayang]#

谢谢支持!!!



你可能感兴趣的:(linux驱动,ioctl命令控制,点亮LED)