这款板子是功能比较强大,我买的是友善之臂的,大家想学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");
#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;
}
一个简单的按键驱动就写完了,如果不知道怎么使用那些工具的,私信我。