免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5981 | 回复: 4
打印 上一主题 下一主题

中断wait_event_interruptible(wq, flag != 0)问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-19 11:28 |只看该作者 |倒序浏览
我写了个简单的中断程序:



#define IRQ_ADC_FIQ  AT91_PIN_PB29



#define ADS_CHANNEL_COUNT 4
#define NAME   "gpiotest"
#define TS_PB29  1<<29




static struct cdev ads7852_cdev;
static int major=0;




static DECLARE_WAIT_QUEUE_HEAD(wq);
static struct semaphore sem;
static int flag = 0;



void pio_init(void)
{
  ((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_IER=TS_PB29;
  ((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_PER=TS_PB29;
   ((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_ODR=TS_PB29;
   ((AT91PS_SYS)AT91C_VA_BASE_SYS)->PIOB_PPUER=TS_PB29;
  
}



/******************************************************************************/
static irqreturn_t ads7852_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{

printk(KERN_ERR"AD_DATA ch0: %x\n",data);
flag = 1;
wake_up_interruptible(&wq);



printk("Interrupted: The %u channel data: %u\n", cur_ch, data);



return IRQ_HANDLED;
}



/******************************************************************************/
static ssize_t ads7852_read(struct file *file,char *buf,
       size_t count, loff_t *ppos)
{




  //进入临界区
if(down_interruptible(&sem)) return -ERESTARTSYS;



//让读进程先睡觉,一直到中断发生时中断来唤醒它
printk( "process %i (%s) going to sleep\n",
  current->pid, current->comm);
wait_event_interruptible(wq, flag != 0);
flag = 0;
printk("awoken %i (%s)\n", current->pid, current->comm);
   
up(&sem);


}



/******************************************************************************/
static ssize_t ads7852_open(struct inode *inode, struct file *file)
{
int retval= request_irq( IRQ_ADC_FIQ, ads7852_int_handler,
  SA_INTERRUPT, NAME, NULL );



if(retval==0)
  printk(KERN_WARNING"request_irq result success\n");



else {
  if(retval==-EBUSY)
   printk(KERN_WARNING"request_irq result BUSY\n");
  else
   printk(KERN_WARNING"request_irq result BUSYING\n");



  return -EFAULT;
}
printk(KERN_WARNING"init interrupte\n");
}



/******************************************************************************/
static ssize_t ads7852_release(struct inode *inode, struct file *flip)
{
free_irq(IRQ_ADC_FIQ,NULL);
return 0;
}



/******************************************************************************/
struct file_operations ads7852_fops=
{
.owner = THIS_MODULE,
.read = ads7852_read,
.open = ads7852_open,
.release = ads7852_release
};



/******************************************************************************/
static int __init ads7852_init(void)
{
int retval = 0;
dev_t dev_id;
pio_init();
at91_set_deglitch(AT91_PIN_PB29,1);
set_irq_type(AT91_PIN_PB29,IRQT_RISING);
if(major) {
  //注册主设备号
  dev_id = MKDEV(major,0);
  retval = register_chrdev_region( dev_id, ADS_CHANNEL_COUNT, NAME);
  if(retval < 0) printk(KERN_WARNING"can't register major number\n");
} else {
  //分配主设备号
  retval = alloc_chrdev_region(&dev_id, 0 ,ADS_CHANNEL_COUNT, NAME);
  if (retval <0 )printk(KERN_WARNING"can't alloc major number\n");



  m
}



printk(KERN_WARNING"major=%d\n", major);



//向内核注册设备
cdev_init(&ads7852_cdev, &ads7852_fops);
ads7852_cdev.owner = THIS_MODULE;
ads7852_cdev.ops = &ads7852_fops;
if( cdev_add(&ads7852_cdev, dev_id, ADS_CHANNEL_COUNT) ) {
  printk(KERN_WARNING"cdev_add error!\n");
}



//初始化互斥锁
init_MUTEX(&sem);



printk(KERN_WARNING"module load sucess\n");



return 0;
}



/******************************************************************************/
static void __exit ads7852_exit(void)
{
dev_t dev_id = MKDEV(major,0);
cdev_del(&ads7852_cdev);
unregister_chrdev_region(dev_id,ADS_CHANNEL_COUNT);



}



/******************************************************************************/
module_init(ads7852_init);
module_exit(ads7852_exit);



但是我发现程序运行到:



request_irq     result success
init interrupte
process 828 (testgpio) going to sleep



然后程序就死在这里了,说明根本就没有唤醒中断服务程序,我仔细检查了所写的程序,没有发现什么问题,各位能给指导下吗?为什么中断服务程序就是唤醒不了

论坛徽章:
0
2 [报告]
发表于 2007-12-20 18:32 |只看该作者
这个是个什么中断?IO类型中断?level sensitive or edge ?
我也想知道怎么回事

论坛徽章:
0
3 [报告]
发表于 2007-12-25 10:20 |只看该作者
原帖由 hijohnny 于 2007-12-20 18:32 发表
这个是个什么中断?IO类型中断?level sensitive or edge ?
我也想知道怎么回事

这个是IO类型中断

论坛徽章:
0
4 [报告]
发表于 2007-12-25 12:50 |只看该作者
你只注册了中断,未操作产生中断的reg

论坛徽章:
0
5 [报告]
发表于 2007-12-27 22:35 |只看该作者
我现在能够产生中断了,但是只产生一次中断后就死在睡眠函数那里了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP