1

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

我没有修改代码并对其进行了测试。我获得了两个设备(/dev/cfake0 和 /dev/cfake1),但我想了解一些东西。

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

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

4

1 回答 1

2

您对文件的每个调用都有一个函数:

  • 开幕
  • 阅读
  • 写作
  • 关闭
  • ...

但是所有函数都有一个struct fileas 参数。

这个包含文件信息的结构是由模块在内核加载时创建的。(见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);
}

话虽如此,我认为在一个模块中有两种不同的协议不是一个好主意(除非两个设备必须共享数据):在模块崩溃时,您将失去两个通信通道,并且模块将难以调试.

于 2017-06-20T14:48:51.900 回答