【问题标题】:How to use a FIFO in a Linux char device driver so that two process that uses the driver can communicate如何在 Linux char 设备驱动程序中使用 FIFO,以便使用该驱动程序的两个进程可以通信
【发布时间】:2014-01-02 21:32:17
【问题描述】:

我有一个用于虚拟设备的字符设备驱动程序。我想要设备驱动程序中的 FIFO,以便使用设备驱动程序的 2 个进程可以在它们之间传输字符。我试过 kfifo,但我是新手,发现它很难使用。任何人都可以建议一些其他方法来在 Linux 驱动程序中实现 FIFO。

【问题讨论】:

  • 为什么需要设备驱动程序而不是普通的named pipe
  • 我不需要两个进程之间的普通命名管道。我需要将使用它的进程写入设备的字符传输到另一台同类设备。

标签: linux pipe ipc linux-device-driver mkfifo


【解决方案1】:

如果您只允许两个进程使用驱动程序,那么您可以这样做: 在您的open 处理程序中,确保两个且只有两个进程可以进入驱动程序:

If access mode = READ and not alreadyreading then
  alreadyreading = 1
else
  return -EBUSY

If access mode = WRITE and not alreadywritting then
  alreadywritting = 1
else
  return -EBUSY

在同一个处理程序中,初始化您的 FIFO,它可能只是一个全局字符变量和两个等待队列:一个用于读取,一个用于写入。与这些队列相关联的是两个变量:ready_to_read 和 ready_to_write。开始时,ready_to_read = 0 和 ready_to_write = 1。

然后,在release 处理程序中:

If access mode = READ
  alreadyreading = 0;
If access mode = WRITE
  alreadywritting = 0

允许新进程以读取或写入模式打开设备。

write 处理程序中:

If access mode = READ then  // we only support writting if the access mode is write
  return -EINVAL
Else
  res = wait_event_interruptible (write_queue, ready_to_write);
  if (res)
    return res;  // if process received a signal, exit write
  Take a single character from user space (copy_from_user() )
  Copy it to the FIFO (the global character variable)
  ready_to_write = 0;  // no more writtings until a read is performed
  ready_to_read = 1;   // ready to read! wake up the reading process
  wake_up_interruptible (&read_queue);
  return 1;  // 1 byte written

最后,在read 处理程序中:

If access mode = READ then  // we only support reading if the access mode is read
  return -EINVAL
Else
  res = wait_event_interruptible (read_queue, ready_to_read);
  if (res)
    return res;  // if process received a signal, exit write
  Take character from global variable (our FIFO) and send it to userspace (copy_to_user() )
  ready_to_read = 0;  // no more reads until a write is performed
  ready_to_write = 1;   // ready to write! wake up the writting process
  wake_up_interruptible (&write_queue);
  return 1;  // 1 byte read

您可以扩展此示例以允许 FIFO 或多个字符:您需要一个字符数组和两个索引:一个知道从哪里读取,一个知道从哪里写入。

要测试您的驱动程序,您可以打开两个 xterm 并执行

cat /dev/mydriver

合而为一,并且:

cat > /dev/mydriver

在另一个。然后,您在第二个 xterm 中编写的每一行都将显示在第一行中。

您甚至可以修改驱动程序,以便在写入过程关闭文件时设置一个标志,以便下次读取过程等待读取某些内容时,它会检测到写入过程已结束,然后它也返回 0 (向用户发出 EOF 信号),因此当您在第二个 xterm 中按 Ctrl-D 结束输入时,第一个也会自动结束。比如:

(read处理程序)

res = wait_event_interruptible (read_queue, ready_to_read || write_process_ended);
if (res)
  return res;  // -ERSTARTSYS if signal
if (write_process_ended)
{
  ready_to_write = 1;
  return 0;    // if write process ended, send an EOF to the user
}
else
{
  ...
  ... get byte from FIFO, send to the user, etc.
  ...
  return number_of_bytes_sent_to_user;
}

【讨论】:

    猜你喜欢
    • 2015-03-21
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 2020-09-06
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多