Chinaunix首页 | 论坛 | 博客
  • 博客访问: 45988
  • 博文数量: 21
  • 博客积分: 855
  • 博客等级: 准尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-20 14:19
文章分类
文章存档

2011年(1)

2009年(20)

我的朋友
最近访客

分类: LINUX

2009-03-20 14:42:58

一.   模块的初始化函数

static int __int s3c24xx_buttons_init(void)

{

       int ret;

      

       ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &3sc24xx_buttons_fops);

       if(ret < 0) {

              printk(DEVICE_NAME" Can not register major number\n");

              return ret;

       }

      

       printk(DEVICE_NAME" inittialized\n");

       return 0;

}

 

二.   模块的退出函数:

static void __exit s3c24xx_buttons_exit(void)

{

       unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);

}

 

三.   指定模块的初始化和退出函数:

module_init(s3c24xx_buttons_init);

module_exit(s3c24xx_buttons_exit);

 

.定义s3c24xx_buttons_fops

static struct file_operations s3c24xx_buttons_fops = {

       .owner = THIS_MODULE,

       .open = s3c24xx_buttons_open,

       .release = s3c24xx_buttons_close,

       .read = s3c24xx_buttons_read

};

 

.编写s3c24xx_buttons_open函数

static int s3c24xx_buttons_open(struct inode *inode, struct file *file)

{

       int i;

       int err;

      

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

              err = request_irq(button_irqs[i].irq, buttons_interrupt, button_irqs[i].flags, button_irqs[i].name, (void *)&press_cnt[i]);

              if(err)

                     break;

       }

      

       if(err) {

              i--;

              for(; i>=0; i--)

                  free_irq(button_irqs[i].irq, (void *)&press_cnt[i]);

             

              return -EBUSY;

       }

      

       return 0;

}

 

.编写close函数:

static int s3c24xx_buttons_close(struct inode *inode, struct file *file)

{

       int i;

      

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

              free_irq(button_irqs[i].irq, (void *)&press_cnt[i]);

       }

      

       return 0;

}

 

.编写read 函数:

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0;

 

static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

{

       unsigned long err;

      

       wait_event_interruptible(button_waitq, ev_press);

       ev_press = 0;

      

       err = copy_to_user(buff, (const void *)press_cnt, min(sizeof(press_cnt), count));

       memset((void *)press_cnt, 0, sizeof(press_cnt));

      

       return err ? -EFAULT : 0;

}

 

8.编写中断函数

 

static irqreturn_t buttons_interrupt(int irq, void *dev_id)

{

       volatile int *press_cnt = (volatile int *)dev_id;

      

       *press_cnt = *press_cnt + 1;

       ev_press = 1;

       wake_up_interruptible(&button_waitq);

      

       return IRQ_RETVAL(IRQ_HANDLED);

}

 

.添加宏定义等:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define DEVICE_NAME     "buttons"   /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */

#define BUTTON_MAJOR    232         /* 主设备号 */

 

/* 按键被按下的次数(准确地说,是发生中断的次数) */

static volatile int press_cnt [] = {0, 0, 0, 0};

 

.s3c24xx_button.c放以内核源码目录drivers/char,drivers/char/Makefile中增加如下一行:

Obj-m +=s3c24xx_button.o

 

.在内核目录下执行 make modules,可以driver/char目录下生成可加载模块s3c24xx_buttons.ko

 

十一.在开发板上:mknod /dev/buttons c 232 0

 

 

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