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

comdoc comdoc 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
问题简介:
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;
}
...全文
评论 5
收藏 已收藏
分享
返回顶部
comdoc
Linux_Kernel 4,469 成员 17,458 内容