linux io的轮询,在Linux内核模块中实现轮询

Sam Protsenk..

8

放弃

嗯,这是一个很好的架构问题,它暗示了一些关于硬件和所需用户空间接口的假设.因此,让我跳出结论进行更改,并尝试猜测哪种解决方案最适合您的情况.

设计

考虑到您未提及write()操作的帐户,我将进一步假设您的硬件始终在生成新数据.如果是这样,你提到的设计可能正是令你困惑的:

该read调用非常简单.它启动DMA写入,然后等待等待队列.

这正是阻止您以常规,常用(以及可能对您而言)方式使用驱动程序的原因.让我们开箱即用,首先想出用户界面(如何从用户空间使用你的驱动程序).下一个案例在这里常用且充足(从我的观点来看):

poll() 您的设备文件等待新数据到达

read() 您的设备文件以获取到达的数据

现在您可以看到请求(到DMA)的数据应该不是通过read()操作来启动的.正确的解决方案将是连续驾驶者读取数据(未经用户空间任何触发),并将其存储在内部,当用户请求你的驱动程序的数据消费(通过read()操作) -为用户提供内部存储的数据.如果驱动程序内部没有存储数据 - 用户可以使用poll()操作等待新数据到达.

正如您所看到的,这是众所周知的生产者 - 消费者问题.您可以使用循环缓冲区将硬件中的数据存储在驱动程序中(因此当缓冲区已满时故意丢失旧数据以防止缓冲区溢出情况).因此,生产者(DMA)写入该RX环形缓冲区的头部,而消费者(用户read()空间执行的用户)从该RX环形缓冲区的尾部读取.

代码参考

这一切情况让我想起了串行控制台 [ 1,2 ]的驱动程序.因此,请考虑在驱动程序实现中使用串行API(如果您的设备实际上是串行控制台).例如,请参阅drivers/tty/serial/atmel_serial.c驱动程序.我对UART API并不是很熟悉,所以我无法准确地告诉你那里发生了什么,但乍一看它看起来并不太难,所以可能你可以从那个代码中找到一两件事你的司机设计.

如果您的驱动程序不应使用Serial API,则可以使用下一个驱动程序进行引用:

补充

在评论中回答你的问题:

如果没有可用的数据并且应该阻止,你建议read打电话吗?pollread

首先,您想决定是否要提供:

阻止I/O.

或两者兼而有之

让我们假设(为了争论)你想在你的驱动程序中提供这两个选项.在这种情况下,open()如果flags参数包含O_NONBLOCK标志,则应检入呼叫.来自man 2 open:

O_NONBLOCK 要么 O_NDELAY

如果可能,文件以非阻塞模式打开.无论是open()也不在其返回将导致调用进程等待的文件描述符的任何后续操作.有关处理FIFO(命名管道)的信息,另请参阅fifo(7).有关O_NONBLOCK与强制文件锁和文件租约一起使用的效果的讨论,请参阅fcntl(2).

现在,当您了解用户选择的模式时,您可以执行下一步(在您的驱动程序中):

如果flagsin open()不包含此类标志,则可以执行阻塞read()(即,如果数据不可用,请等待DMA事务完成然后返回新数据).

但如果O_NONBLOCK在open()标志并没有在循环缓冲区可用数据-你应该返回read()调用与EWOULDBLOCK错误代码.

EAGAIN 要么 EWOULDBLOCK

文件描述符fd引用套接字并且已标记为nonblocking(O_NONBLOCK),并且读取将阻塞.POSIX.1-2001允许在这种情况下返回错误,并且不要求这些常量具有相同的值,因此便携式应用程序应检查这两种可能性.

您还可以阅读下一篇文章,以便更好地掌握相应的界面:

补充2

我需要某种后台任务,不断从设备读取并填充环形缓冲区.poll现在是微不足道的 - 只是检查缓冲区中是否有任何东西,但read更难,因为它可能需要等待将某些内容发布到环形缓冲区.

在poll()函数中:do poll_wait()(等待新数据到达)

在接收数据中断处理程序中:do wake_up_interruptible()(唤醒poll和read操作)

在read()函数中:

如果端口没有数据:

如果O_NONBLOCK设置了标志(在open()操作中):return -EAGAIN= -EWOULDBLOCK立即

否则我们有阻塞读取:wait_event_freezable()等待新数据到达

如果端口有数据:从缓冲区返回数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值