【发布时间】:2017-06-14 11:20:11
【问题描述】:
假设我有一个外部设备不断将数据推送到驱动程序中的一个小缓冲区中。我正在使用等待队列,其中中断处理程序唤醒等待的用户进程(类似于 LDD (3rd edition) - 实现处理程序)。
irq_handler_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
flag = 1;
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
ssize_t my_read(struct file *dev, char __user *buf, size_t count, loff_t *f_pos)
{
wait_event_interruptible(wq, flag != 0);
flag = 0;
copy_to_user(usr_buf, drv_buf, count);
}
/***********************User program***********************/
while(1)
{
read(fid, buffer, size);
//do stuff with data
}
用户程序调用 read 并等待中断从外部设备获取新数据。由于外部设备可能会以比此代码执行速度更快的速度推送数据,我可以使用哪些机制来确保在用户程序复制数据之前不会覆盖数据?像结构这样的环形缓冲区会在这里工作吗?不清楚如何实现。
谢谢
【问题讨论】:
-
你的 drv_buf 如何获取数据? copy_to_user(usr_buf, drv_buf, count) 应该是 copy_to_user(buf, drv_buf, count)。
-
“我可以使用什么机制来确保数据在用户程序复制之前不会被覆盖?” -- 本质上,驱动程序只能尽可能多地缓冲,直到那里是缓冲区溢出。 (静态分配的)环形缓冲区(如答案中所提议的)仅在(环形)缓冲区大小不足时才能推迟溢出。编写良好的驱动程序将能够检测并报告这种情况。即使是动态分配的缓冲区也可能不足以应付“慢”的阅读器。 IOW 你必须确保用户空间至少能以某种平均速率跟上到达的数据。
标签: c linux linux-kernel linux-device-driver