LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1352|回复: 0

关于中断的内核模块?查了半天不明白

[复制链接]
发表于 2007-12-14 23:35:48 | 显示全部楼层 |阅读模式
一个很简单的驱动程序(初学),控制8253模拟电子琴的,驱动程序在下面
本来只是播放一段声音的话,没有问题,但是考虑要模拟琴键按下才响的情况,学着加了中断,可是确实不行,直接编译模块的地方就过不去了,我的linux是 opensuse10.3,内核2.6.22.5,在request_irq地方出错,如果直接request的话,死机,不能动弹,放在if后面显示编译有warning
/home/yuan/Desktop/demo1/beep.c:   In   function   ‘init_module’:
/home/yuan/Desktop/demo1/beep.c:123:   warning:   passing   argument   2   of   ‘request_irq’   from   incompatible   pointer   type
如果采用request_irq(1,   key_handler,   SA_INTERRUPT,   "beep",   NULL)的话,还有一个‘deprecated_irq_flag’   is   deprecated   (declared   at   /usr/src/linux-2.6.22.5-31/include/linux/interrupt.h:66)
直接加载模块的话,提示出错insmod:   error   inserting   'beep.ko':   -1   Input/output   error

大家帮帮忙阿,头一回写中断,晕死了,看了书,看了网上的材料还是不明白

//beep.h
#ifndef   __BEEP_H__
#define   __BEEP_H__

#define   MAJOR_NUM   145 //   no   dynamic   Major   number
#define   DEVICE_NAME   "beep" //   The   name   for   our   device
#define BEEPSETCFG _IOR('c',   0,   int)
#define BEEPSTART _IOR('c',   1,   int)
#define BEEPSTOP _IOR('c',   2,   int)

#endif


//beep.c
#include   <linux/kernel.h>
#include   <linux/module.h>
#include   <asm/io.h>

#if   CONFIG_MODVERSIONS==1
#define   MODVERSIONS
#endif

#include   <linux/fs.h>
#include   <linux/delay.h>
#include   <asm/uaccess.h>
#include   <linux/sched.h>
#include   <linux/spinlock.h>
#include   <linux/init.h>
#include   <linux/interrupt.h>
#include   <asm/irq.h>
#include   <asm/signal.h>
#include   <asm/uaccess.h>

#include   "beep.h"
#define   SUCCESS   0

static   int   Device_Open   =   0;

static   spinlock_t   key_lock   =   SPIN_LOCK_UNLOCKED;

static   irqreturn_t   key_handler(int   irq,   void   *dev_id,   struct   pt_regs   *regs);
static   void   key_task(unsigned   long   data);

DECLARE_TASKLET(key_tasklet,   key_task,   0);

static   int   beep_open(struct   inode   *inode,struct   file   *file){
printk("beep   driver   opened\n");
if(Device_Open) return   -EBUSY;
Device_Open   ++;
return   SUCCESS;
}

static   int   beep_release(struct   inode   *inode,struct   file   *file){
Device_Open   --;
return   0;
}

int   beep_read(struct   file   *file,char   *buffer,size_t   length,loff_t   *offset){
return   0;
}

int   beep_write(struct   file   *file,char   *buffer,size_t   length,loff_t   *offset){
return   0;
}

int   beep_ioctl(struct   inode   *inode,struct   file   *file,unsigned   int   cmd,unsigned   long   arg){
int   retval,bit;
retval   =   0;
bit   =   0;
switch(cmd){
case   BEEPSETCFG:
outb(0xb6,0x43);
outb((arg   &   0xff),0x42);
outb((arg   > >   8),0x42);
break;
case   BEEPSTART:
bit=inb(0x61);
outb(3   ¦   bit,0x61);
break;
case   BEEPSTOP:
outb(0xfc   ¦   bit,0x61);
break;
default:
retval   =   -ENOIOCTLCMD;
break;
}
return   retval;
}

struct   file_operations   Fops   =   {
.owner =THIS_MODULE,
.open =beep_open,
.release =beep_release,
.ioctl =beep_ioctl,
.read =beep_read,
.write =beep_write,
};

static   irqreturn_t   key_handler(int   irq,   void   *dev_id,   struct   pt_regs   *regs)
{
disable_irq(1);
tasklet_schedule(&key_tasklet);
return   IRQ_RETVAL(1);
}

static   void   key_task(unsigned   long   data){
unsigned   long   flags;
int   bit;
spin_lock_irqsave(&key_lock,   flags);
{
bit=inb(0x61);
outb(3   ¦   bit,0x61);
}
spin_unlock_irqrestore(&key_lock,   flags);
outb(0xfc   ¦   bit,0x61);
return;
}


int   init_module(){
int   ret_val;
unsigned   long   flags;
ret_val   =   register_chrdev(MAJOR_NUM,DEVICE_NAME,&Fops);
printk(" <1> -----\n");
if   (ret_val   <   0)   {
printk   ("%s   failed   with   %d\n","?Sorry,   registering   the   character   device   ",ret_val);
return   ret_val;
}
free_irq(1,   NULL);
printk(" <1> free_irq(1,   NULL);\n");
                spin_lock_irqsave(&key_lock,   flags);
if   (request_irq(1,key_handler,0,"beep",   NULL)){
printk(KERN_ERR"cannot   register   IRQ   1+++%d\n",-EIO);
return   -EIO;
}
request_irq(1,   key_handler,   SA_INTERRUPT,   "beep",   NULL);
disable_irq(1);
spin_unlock_irqrestore(&key_lock,   flags);
return   0;
}

void   cleanup_module()
{
int   ret;
ret   =   unregister_chrdev(MAJOR_NUM,   DEVICE_NAME);
if   (ret   <   0)
printk("Error   in   module_unregister_chrdev:   %d\n",   ret);
free_irq(1,NULL);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表