hughchiu
驱动牛犊
驱动牛犊
  • 注册日期2004-07-23
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1203回复:3

一个比较怪的中断程序,大家帮帮忙

楼主#
更多 发布于:2004-08-01 22:26
以下的是一个完整的驱动程序模块,根据ldd2的short改编的, 编译通过, 加载成功, 加载后读/proc/interrupts 文件发现程序成功注册了irq号, 第一次触发中断时,程序有反应,有输出信息,第二次触发中断时,就不会打印任何东西了,而且rmmod的时候会有问题,请大家多多帮忙

谢谢!

//linux 内核版本: 2.4.19
//----------------------------------------------------------------
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif

#include <linux/config.h>
#include <linux/module.h>

#include <linux/sched.h>
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/delay.h> /* udelay */
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/tqueue.h>

#include <asm/io.h>

#include "sysdep.h"
#define SHORT_NR_PORTS 2
#define base 0x08000010

static int major=0;//dynamic by default
static unsigned int blr_mask=0;
static unsigned int blr_mask_org=0;
static unsigned int status=0;

static void * short_base;

volatile int short_irq = -1;

static int i=0;

int short_i_open (struct inode *inode, struct file *filp)
{
return 0;
}


int short_i_release (struct inode *inode, struct file *filp)
{
return 0;
}

struct file_operations short_i_fops = {
open: short_i_open,
release: short_i_release,
};

void short_tl_interrupt(int irq, void *dev_id, struct pt_regs *regs)//中断服务程序
{
printk("\nin short_tl_interrupt!\n");
i++;
}

int short_init(void) //模块初始化
{
int result;
SET_MODULE_OWNER(&short_i_fops);

/* Get our needed resources. */
result = check_region(base, SHORT_NR_PORTS);
if (result)
{
printk(KERN_INFO "short: can't get I/O port address 0x%lx\n",
base);
return result;
}

request_region(base, SHORT_NR_PORTS, "short");

result = register_chrdev(major, "short", &short_i_fops);
if (result < 0)
{
printk(KERN_INFO "short: can't get major number\n");
release_region(base,SHORT_NR_PORTS);//fail to get major release resource
return result;
}
if (major == 0)
major = result; /* dynamic */

short_base = ioremap(base, SHORT_NR_PORTS);
short_irq=26; //固定中断号

if (short_irq >= 0)
{
result = request_irq(short_irq,short_tl_interrupt,SA_INTERRUPT,"test joystick", NULL);
if (result)
{
printk(KERN_INFO "short-bh: can't get assigned irq %i\n",
short_irq);
short_irq = -1;
}
else
{
blr_mask_org=inw(short_base);
outw(blr_mask_org|0x2000,short_base);
}
}

if(short_irq>0)
return 0;//success
else
return short_irq;//fail

printk("%d\n",i);
}

void short_cleanup(void)
{
iounmap(short_base);//unmap
release_region(base,SHORT_NR_PORTS);//release region
if (short_irq >= 0)
{
outw(blr_mask_org,short_base); /* disable the interrupt */
free_irq(short_irq, NULL);
}

unregister_chrdev(major, "short");
printk("%d\n",i);
}

module_init(short_init);
module_exit(short_cleanup);
lehua
驱动牛犊
驱动牛犊
  • 注册日期2002-12-05
  • 最后登录2004-08-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-08-09 13:49
Are you sure you have entered you interrupt handler? I don't know what kind of hardware you have, but I think you have to clean the hardware interrupt status in you interrupt handler.
Hello, World!
madmanexe
驱动牛犊
驱动牛犊
  • 注册日期2004-03-27
  • 最后登录2008-01-04
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-08-11 16:25
中断处理程序有问题
关掉中断之后是否在处理之后打开中断?
rainyss
驱动牛犊
驱动牛犊
  • 注册日期2004-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-08-13 12:20
毛病在哪我没看出来,不过另一种事要注意,中断里面不要做printk,会出毛病的
游客

返回顶部