字符设备:选择要read/write的设备
character device: choose the device to read/write
我找到了一个很好的代码作为字符设备模块的示例:https://github.com/euspectre/kedr/blob/master/sources/examples/sample_target/cfake.c
我没有修改代码,我测试了它。我获得了两个设备(/dev/cfake0 和 /dev/cfake1),但我想了解一些东西。
导出了两个设备,但只有一个读取功能,如何指定每个设备使用哪个读取功能(如果实现了两个读取功能)?
最后我想在同一个模块上有两个字符设备(一个用于I2C通信,另一个用于SPI),模块和用户-space需要通信所以我需要导出他们两个。
您的文件中的每个调用都有一个函数:
- 开幕
- 阅读
- 写作
- 关闭
- ...
但是所有函数都有一个 struct file
作为参数。
此结构(包含有关文件的信息)是模块在内核中加载时创建的。 (参见 static int __init cfake_init_module(void);
函数)。
In the end I would like to have two character devices (one for I2C communication, another one for 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);
}
也就是说,我认为在一个模块中使用两种不同的协议不是一个好主意(除非两个设备必须共享数据):在模块崩溃时,您将失去两个通信通道,并且模块将很难调试。
我找到了一个很好的代码作为字符设备模块的示例:https://github.com/euspectre/kedr/blob/master/sources/examples/sample_target/cfake.c
我没有修改代码,我测试了它。我获得了两个设备(/dev/cfake0 和 /dev/cfake1),但我想了解一些东西。
导出了两个设备,但只有一个读取功能,如何指定每个设备使用哪个读取功能(如果实现了两个读取功能)?
最后我想在同一个模块上有两个字符设备(一个用于I2C通信,另一个用于SPI),模块和用户-space需要通信所以我需要导出他们两个。
您的文件中的每个调用都有一个函数:
- 开幕
- 阅读
- 写作
- 关闭
- ...
但是所有函数都有一个 struct file
作为参数。
此结构(包含有关文件的信息)是模块在内核中加载时创建的。 (参见 static int __init cfake_init_module(void);
函数)。
In the end I would like to have two character devices (one for I2C communication, another one for 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);
}
也就是说,我认为在一个模块中使用两种不同的协议不是一个好主意(除非两个设备必须共享数据):在模块崩溃时,您将失去两个通信通道,并且模块将很难调试。