基于S5PV210板驱动开发之按键驱动

这款板子是功能比较强大,我买的是友善之臂的,大家想学arm入手这款板子还不多,这里我们就介绍一下怎么写一个按键驱动的代码:

mybuton.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <mach/gpio.h>
#include <linux/cdev.h>
#include <linux/interrupt.h>

int major=200;
static struct class *button_class;
static struct class_device  *button_class_dev;
//volatile unsigned int* GPJ2CON=NULL;
//volatile unsigned int* GPJ2DAT=NULL;
const int led_pin[4]={
	S5PV210_GPJ2(0),
	S5PV210_GPJ2(1),
	S5PV210_GPJ2(2),
	S5PV210_GPJ2(3),
};

struct _button_desc{
	int button_pin;
	int number;
	char *name;
};


const struct _button_desc button_desc[8]={
	{S5PV210_GPH2(0),0,"key0"},
	{S5PV210_GPH2(1),1,"key1"},
	{S5PV210_GPH2(2),2,"key2"},
	{S5PV210_GPH2(3),3,"key3"},
	{S5PV210_GPH3(0),4,"key4"},
	{S5PV210_GPH3(1),5,"key5"},
	{S5PV210_GPH3(2),6,"key6"},
	{S5PV210_GPH3(3),7,"key7"},
};

struct cdev button_cdev;
irqreturn_t button_handler(int irq,void *dev)
{
	int i;
	struct _button_desc *button_temp=(struct _button_desc* )dev;
	for(i=0;i<4;i++)
	{
		gpio_set_value(led_pin[i],1);
	}

	gpio_set_value(led_pin[button_temp->number/2],0);
	/*for(i=0;i<8;i++)
	{
		if(irq==gpio_to_irq(button_pin[i]))
			{
				gpio_set_value(led_pin[i/2],0);
			}
	}*/
	return IRQ_HANDLED;
}

//打开文件函数
int button_open(struct inode *pinode, struct file * pfile)
{
	/*GPJ2CON=(volatile unsigned int *)ioremap(0xE0200280,4);
	*GPJ2CON=0x1111;

	GPJ2DAT=(volatile unsigned int *)ioremap(0xE0200284,1);
	*GPJ2DAT=0xf;
	volatile unsigned int* base_addr=ioremap(0xE0200280,8);
	GPJ2CON=base_addr+0;
	writel(0x1111,GPJ2CON);

	GPJ2DAT=base_addr+1;

	writel(0xf,GPJ2DAT);*/
	//申请GPIO端口
	int i;
	for(i=0;i<4;i++)
	{
		int r=gpio_request(led_pin[i],"myled");
		if(r<0)
			printk("request error\n");//等级GPIO端口
	}

	for(i=0;i<4;i++)
	{
		gpio_direction_output(led_pin[i],1);//将编号对应引脚设置为输出
	}

	for(i=0;i<8;i++)
	{

		int r;
		r=request_irq(gpio_to_irq(button_desc[i].button_pin),button_handler,IRQF_TRIGGER_FALLING,button_desc[i].name,(void *)&button_desc[i]);
		if(r!=0)
			{
				printk("request_irq error\n");
			}
	}
	return 0;
}

ssize_t button_write(struct file *pfile,const char __user *buffer,size_t const count,loff_t *loff)
{
	char data=0;
	copy_from_user(&data,buffer,1);
	if(data>4||data<1)
	{
		return -1;
	}
	gpio_set_value(led_pin[data-1],0);
	return 0;
}

/*long led_ioctl(struct file* pfile,unsigned int cmd,unsigned long arg)
{
	char data=arg;
	if(cmd==1)
	{
		if(data==1)
	{
		writel(0xE,GPJ2DAT);
	}
	if(data==2)
	{
		writel(0xD,GPJ2DAT);
	}
	if(data==3)
	{
		writel(0xB,GPJ2DAT);
	}
	if(data==4)
	{
		writel(0x7,GPJ2DAT);
	}
	}
	
	//copy_from_user(&data,buffer,1);
	
}*/
static struct file_operations button_ops=
{
	.owner=THIS_MODULE,
	.open=button_open,
	.write=button_write,
	//.unlocked_ioctl=led_ioctl,
};



//初始化函数
static  __init int myinit(void)//限制这个函数在这个文件中
{
	printk("My first module\n");
	//register_chrdev(major,"myled",&led_ops);

	register_chrdev_region(MKDEV(major,0),1,"mybutton");
	cdev_init(&button_cdev,&button_ops);
	cdev_add(&button_cdev,MKDEV(major,0),1);
	
	//alloc_chrdev_region(dev_t * dev,unsigned baseminor,unsigned count,const char * name)
	button_class=class_create(THIS_MODULE,"mybutton");
	button_class_dev=device_create(button_class,NULL,MKDEV(major,0),NULL,"mybutton");
	return 0;
} 

module_init(myinit);

//退出函数
static __exit void myexit(void)
{
	printk("Goodbye my module\n");

	//设备销毁 删除./dev下的文件
	device_destroy(button_class,MKDEV(major,0));

	//设备类的销毁
	class_destroy(button_class);

	//注销设备
	//unregister_chrdev(major,"myled");
	cdev_del(&button_cdev);

	int i;
	for(i=0;i<4;i++)
	{
		gpio_free(led_pin[i]);
	}
	for(i=0;i<8;i++)
	{
		free_irq(gpio_to_irq(button_desc[i].button_pin),NULL);
	}

	return 0;
}

module_exit(myexit);

//模块许可声明
MODULE_LICENSE("GPL");//这个必须要

MODULE_AUTHOR("haha");

MODULE_DESCRIPTION("haha");


main.c

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

int main(int argc,char* argv[])
{
	char* name="/dev/mybutton";
	int fd=open(name,O_RDWR);
	char buffer;
	if(fd<0)
	{
		printf("open %m\n");
	}
	//int cmd=atoi(argv[1]);
	/*buffer=atoi(argv[1]);
	int r=write(fd,&buffer,1);
	if(r<0)
	{
		printf("write:%m\n");
	}
	//ioctl(fd,cmd,buffer);*/
	return 0;
}

一个简单的按键驱动就写完了,如果不知道怎么使用那些工具的,私信我。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值