Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178386
  • 博文数量: 43
  • 博客积分: 2516
  • 博客等级: 少校
  • 技术积分: 500
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-09 10:25
文章分类

全部博文(43)

文章存档

2011年(1)

2009年(11)

2008年(31)

我的朋友

分类: 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/2.6.24下。

3、在任意目录下建立keytest.c文件,并且交叉编译生成二进制文件,如:root@dc-desktop:/home/dc/arm/linux-2.6.24/drivers/char# arm-none-linux-gnueabi-gcc -o keytest keytest.c keytest下载到开发板上,利用chmod +x keytest修改权限,然后运行既可。

     此驱动及测试函数完成了对9261-EK上的一个按键中断方式的驱动,此按键接在PA27脚上,运行keytest之后按下按键终端即会显示出按键被按下的次数,次数大于10之后退出程序。

按键驱动程序如下:
#include
#include
#include
#include
#include
#include   /* get the user-level API */
#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;
    }
    }
}

 

 

阅读(6033) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-05-06 16:26:29

而且你在kirq_init中,根本没有cdev_add设备,

chinaunix网友2010-05-06 16:24:30

你省略了一些程序吧?没有kirq_open函数,你再用户空间怎么可能能打开这个设备?