2013-10-13 实验之ioctl控制Led

实验描述:ioctl控制LED

注意事项:unlocked_ioctl(...)是控制32bit

内核版本:Linux 2.6.38

开发板:  Mini 6410


驱动程序:

#include <linux/init.h>  
#include <linux/module.h>  
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>  
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h> 
/*
      Kernel Version: Linux 2.6.38
      Arm Version: Mini 6410
*/

#define MyPrintk  printk
#define CTL_Led1 3
#define CTL_Led2 4
#define CTL_Led3 5
#define CTL_Led4 6

static dev_t  Leds_Major ;
static char * DEVICE_NAME = "IoctlLeds";
volatile unsigned long *gpkcon0 = NULL;
volatile unsigned long *gpkdat    = NULL;
static struct class *leds_class;


static int   buttons_leds_init (struct inode *inode, struct file *file)
{
	*gpkcon0 &= ~( (0xF<<4*4) | (0xF<<5*4) | (0xF<<6*4) | (0xF<<7*4));
	*gpkcon0 |= ( (0x1<<4*4) |(0x1<<5*4) | (0x1<<6*4) | (0x1<<7*4));
	*gpkdat |= (1<<4) | (1<<5) | (1<<6) | (1<<7) ;  
	return 0;
}


long unlocked_ioctl_leds (struct file * file, unsigned int cmd, unsigned long count)
{	
	MyPrintk (KERN_EMERG "unlocked Cmd value: %d, %lu\n", cmd, count);   
	*gpkdat |= (1<<4) | (1<<5) | (1<<6) | (1<<7) ;  
	if( cmd == CTL_Led1){	
		*gpkdat &= ~ ((1<<4) | (0<<5) | (0<<6) | (0<<7)) ;		
	}else if(cmd == CTL_Led2){
		*gpkdat &= ~ ((0<<4) | (1<<5) | (0<<6) | (0<<7));
	
	}else if(cmd == CTL_Led3){
		*gpkdat &= ~ ((0<<4) | (0<<5) | (1<<6) | (0<<7));
		
	}else if(cmd == CTL_Led4){
		*gpkdat &= ~ ((0<<4) | (0<<5) | (0<<6) | (1<<7));
	}
	return 0;
}

long compat_ioctl_leds (struct file * file, unsigned int cmd , unsigned long count)
{
	MyPrintk (KERN_EMERG "locked Cmd value: %d, %lu\n", cmd, count);   
	*gpkdat |= (1<<4) | (1<<5) | (1<<6) | (1<<7) ;  
	if( cmd == CTL_Led1){	
		*gpkdat &= ~ ((1<<4) | (0<<5) | (0<<6) | (0<<7)) ;		
	}else if(cmd == CTL_Led2){
		*gpkdat &= ~ ((0<<4) | (1<<5) | (0<<6) | (0<<7));
	
	}else if(cmd == CTL_Led3){
		*gpkdat &= ~ ((0<<4) | (0<<5) | (1<<6) | (0<<7));
		
	}else if(cmd == CTL_Led4){
		*gpkdat &= ~ ((0<<4) | (0<<5) | (0<<6) | (1<<7));
	}
	return 0;
}

static struct file_operations  s3c64XX_leds_fops = {
	.owner = THIS_MODULE,
	.open = buttons_leds_init,
	.compat_ioctl = compat_ioctl_leds,
	.unlocked_ioctl = unlocked_ioctl_leds,

};

static int myleds_init(void)  
{   
	Leds_Major = register_chrdev(Leds_Major,DEVICE_NAME , &s3c64XX_leds_fops);
	if(Leds_Major < 0){
   	  	 MyPrintk (KERN_EMERG "Sorry, Can not register the leds device!\n");  
   	} 
	MyPrintk (KERN_EMERG " Register the  %s device\n", DEVICE_NAME);   
	leds_class = class_create(THIS_MODULE, DEVICE_NAME); 
	device_create(leds_class, NULL , MKDEV(Leds_Major, 0), NULL, DEVICE_NAME);
	gpkcon0 = (volatile unsigned long *)ioremap(0x7F008800,12);
	gpkdat = gpkcon0 + 2; 
	return 0;  
}  

static void myleds_exit(void)  
{   
	unregister_chrdev(Leds_Major, DEVICE_NAME);
  	device_destroy(leds_class,  MKDEV(Leds_Major, 0));	
	class_destroy(leds_class);
	iounmap(gpkcon0);
  	MyPrintk (KERN_EMERG "%s Linux Byebye\n", DEVICE_NAME);  
}  
  
module_init(myleds_init);  
module_exit(myleds_exit);
MODULE_LICENSE("GPL");  


测试程序:

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

#define CTL_Led1 3
#define CTL_Led2 4
#define CTL_Led3 5
#define CTL_Led4 6


int main(int argc, char **argv)
{
	int fd;
	int val = 1;
	int ret;
	fd = open("/dev/IoctlLeds", O_RDWR);
	if (fd < 0){
		printf("Sorry, can't open!\n");
	}

	int arg = 12;
	ret = ioctl(fd, CTL_Led1, &arg);
	if (ret != 0){
		printf("Sorry, can't ioctl!\n");
	}
	sleep(2);

	arg = 11;
	ret = ioctl(fd, CTL_Led2, &arg);
	if (ret != 0){
		printf("Sorry, can't ioctl!\n");
	}
	sleep(2);

	arg = 10;
	ret = ioctl(fd, CTL_Led3, &arg);
	if (ret != 0){
		printf("Sorry, can't ioctl!\n");
	}
	sleep(2);

	arg = 9;
	ret = ioctl(fd, CTL_Led4, &arg);
	if (ret != 0){
		printf("Sorry, can't ioctl!\n");
	}
	sleep(2);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值