字符设备:选择要读/写的设备

时间:2017-06-20 13:56:04

标签: c linux kernel linux-device-driver chardev

我找到了一个很好的代码作为字符设备模块的示例:https://github.com/euspectre/kedr/blob/master/sources/examples/sample_target/cfake.c

我没有修改代码,我测试了它。我获得了两个设备(/ dev / cfake0和/ dev / cfake1),但我想了解一些。

导出了两个设备但只有一个读取功能,如何指定每个设备使用哪个读取功能(如果实现了两个读取功能)?

最后,我希望在同一个模块上有两个字符设备(一个用于I2C通信,另一个用于SPI),模块和用户空间需要通信,因此我需要导出它们。

1 个答案:

答案 0 :(得分:2)

您的文件每次调用都有一个功能:

  • 开口
  • 读取
  • 结束
  • ...

但是所有函数都有struct file作为参数。

这个结构 - 包含有关文件的信息 - 是在模块加载到内核时由模块创建的。 (见static int __init cfake_init_module(void);函数)。

  

最后,我希望有两个字符设备(一个用于I2C通信,另一个用于SPI)

你可以这样做:

在您提供的示例中,每个文件都使用minor device number创建(请参阅cfake_construct_device())。您可以使用此编号来选择设备是SPI还是I2C设备。

您的read功能可能如下所示:

ssize_t 
cfake_read(struct file *filp, char __user *buf, size_t count, 
    loff_t *f_pos)
{
   /* reading minor device number */
   unsigned int mn = iminor(filp->f_inode);

   /* select specialized function to use */ 
   if (0 == mn)
       return cfake_read_i2c(filp, buf, count, f_pos);
   else 
       return cfake_read_spi(filp, buf, count, f_pos);
}

说,我不认为在一个模块中有两个不同的协议是个好主意(除非两个设备必须共享数据):在模块崩溃时,你将松开两个通信通道,并且模块将难以调试。