分类: LINUX
2009-04-30 09:51:48
9261EK上一个按键的驱动及测试
1、在内核目录中driver/char/下面建立一个新的.c文件:keydriver.c,修改当前目录中的Makefile文件,加入:
obj-m += keydriver.o
2、在内核目录下make modules 既可在driver/char/下生成keydriver.ko,将其下载到开发板的lib/modules/
3、在任意目录下建立keytest.c文件,并且交叉编译生成二进制文件,如:root@dc-desktop:/home/dc/arm/linux-
此驱动及测试函数完成了对9261-EK上的一个按键中断方式的驱动,此按键接在PA27脚上,运行keytest之后按下按键终端即会显示出按键被按下的次数,次数大于10之后退出程序。
按键驱动程序如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ATUO_CLEAR_WATCHDOG 0
#define CLEAR_TIMER 100
#define DEBUG 0
#define USE_HEADER 0
#if DEBUG
#define printf(fmt, args...) printk(fmt, ## args)
#else
#define printf(fmt, args...)
#endif
#define kirq_irq 3
MODULE_LICENSE("GPL");
static int KEY_IRQ = 0x00;
static int kirq_dev;
irqreturn_t kirq_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int value;
mdelay(10);//防抖
value=at91_get_gpio_value(AT91_PIN_PA27);//读取IO的值
if(!value)
{
KEY_IRQ++;
printk("KEY_IRQY:%d\r\n",KEY_IRQ);
while(!value) //防死按
value=at91_get_gpio_value(AT91_PIN_PA27);
}
return 0;
}
size_t kirq_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
put_user(KEY_IRQ,(int *)buf);
return 0;
}
static struct file_operations kirq_fops = {
.owner = THIS_MODULE,
.read = kirq_read,
};
static int __init kirq_init(void){
int result;
printk(KERN_ALERT "kirq_test:%s,%s\r\n",__DATE__,__TIME__);
result = register_chrdev(64, "kirq", &kirq_fops);
if (result < 0){
printk("register device fail.\r\n");
return result;
}
at91_set_gpio_input(AT91_PIN_PA27,1);
at91_set_deglitch(AT91_PIN_PA27,0);
result = request_irq(AT91_PIN_PA27,kirq_interrupt, 0, "kirq", &kirq_dev);
if (result < 0){
printk("register irq fail.%d\r\n",result);
return result;
}
return 0;
}
static void __exit kirq_exit(void){
printk("stop kirq\r\n");
free_irq(AT91_PIN_PA27,&kirq_dev);//kirq_interrupt);
unregister_chrdev(64, "kirq");
printk(KERN_ALERT "stop clear kirq\r\n");
}
module_init(kirq_init);
module_exit(kirq_exit);
测试程序如下:
#include
#include
#include
#include
#include
#include
#include
int dev;
int main(void){
int j,temp=0;
int interr_times=0;
printf("test keydacong.\r\n");
system("rmmod keydacong");
system("insmod keydacong");
dev = open("/dev/kirq",O_RDWR);
if(dev == -1){
printf("cann't open kirq \n");
return 0;
}
while(1)
{
read(dev,&interr_times,sizeof(int));
if(interr_times!=temp)
{
printf("interrupt times:%d\r\n",interr_times);
}
temp=interr_times;
if(interr_times >9)
{
close(dev);
system("rmmod keydacong");
break;
}
}
}