read函数中wait_event_interruptible无法唤醒,求助。

comdoc 2011-07-12 10:13:10
问题简介:
1,CPU的一个GPIO口配置为中断响应功能(以确定该口可以配置为中断),高电平触发,该口连接功能芯片的的IRQ口,IRQ口平时为低电平,当有数据要发送给CPU时,IRQ变为高电平,然后CPU读取数据。

2,现在的问题是下面的read函数可以读取第一帧数据,但是之后再调用时会一直挂在wait_event_interruptible处,表现为wait_event_interruptible长时间没有退出。通过示波器观察,确实是有一个中断产生的,IRQ线有一个向高跳变。

求教大家,可能的原因和解决方法,非常感谢。
源码如下:

static ssize_t scull_dev_read(struct file *filp, char __user *buf,
size_t count, loff_t *offset)
{
struct scull_dev *scull_dev = filp->private_data;
char tmp[MAX_BUFFER_SIZE];
int ret;

mutex_lock(&scull_dev->read_mutex);

if (!gpio_get_value(scull_dev->irq_gpio)) {
if (filp->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
goto fail;
}

scull_dev->irq_enabled = true;
enable_irq(scull_dev->client->irq);
ret = wait_event_interruptible(scull_dev->read_wq,
gpio_get_value(scull_dev->irq_gpio));

scull_disable_irq(scull_dev);

if (ret)
goto fail;

}

/* Read data */
ret = i2c_master_recv(scull_dev->client, tmp, count);
mutex_unlock(&scull_dev->read_mutex);

if (ret < 0) {
pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
return ret;
}
if (ret > count) {
pr_err("%s: received too many bytes from i2c (%d)\n",
__func__, ret);
return -EIO;
}
if (copy_to_user(buf, tmp, ret)) {
pr_warning("%s : failed to copy to user space\n", __func__);
return -EFAULT;
}
return ret;

fail:
mutex_unlock(&scull_dev->read_mutex);
return ret;
}
...全文
631 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
comdoc 2011-07-21
  • 打赏
  • 举报
回复
多谢大家的回答,问题找到了,是I2C速率设的太慢了,由于两次读取只给一个中断,速率太慢的话读完第一次,中断就消失了。
Kyph 2011-07-12
  • 打赏
  • 举报
回复
由于缺乏中断等其他处理函数的描述,我只能猜想一下:
1)本应该在中断处理中进行唤醒功能,但是可能中断没有正确执行唤醒功能。
2)休眠工作队列没有初始化。
3)你主动就中断关闭了,如果没有打开的地方,很可能下一次没有打开。
yong_f 2011-07-12
  • 打赏
  • 举报
回复
你没有加中断响应函数吧 
开始领悟 2011-07-12
  • 打赏
  • 举报
回复
把互斥锁去掉试试看
thenshesaid 2011-07-12
  • 打赏
  • 举报
回复
wait_event_interruptible的文档
The process is put to sleep (TASK_INTERRUPTIBLE) until the condition evaluates to true or a signal is received. The condition is checked each time the waitqueue wq is woken up.

wake_up has to be called after changing any variable that could change the result of the wait condition.

你有没有在ISR中wake up?

4,441

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧