我在使用系统调用 read/write 时是否在使用硬件驱动程序?

Am i using the hardware driver while using system call read/write?

我已经通过 i2c 线路将硬件连接到嵌入式 linux 板上。 我可以在 /dev/i2c-1

看到设备
    filename = "/dev/i2c-1"
    filehandle = open(filename,O_RDWR);
    write(filehandle, <buffer to be written>, <number of Bytes>)

(similiarly for  read =   read(filehandle, <buffer to be read in an array>, <number of Bytes>)

现在我的问题是,当我调用写入系统调用(并像上面那样使用文件句柄读取)时,我是否使用了 Linux 的 i2c 驱动程序(read/write)。

这个实现是否独立于i2c模块?我做了modprobe后才验证i2c_dev我可以看到我的代码运行。 是 modprobe i2c_dev 加载 i2c 模块并在 /dev 目录中形成 /dev/i2c-1 因为我已将 i2c 设备连接到它。

用户-space I2C 接口

I2C 子系统的用户-space 接口通过 /dev/i2c-* 文件提供并记录在 Documentation/i2c/dev-interface。 I2C报文发送方式有两种:

  • 通过write()发送普通缓冲区;你需要为此添加 linux/i2c-dev.h
  • 通过 ioctl()I2C_RDWR 请求发送 i2c_msg 结构;你需要为此添加 linux/i2c.h

有关示例,请参阅 this question

/dev/i2c-1 如何与 I2C 子系统关联

/dev/i2c-1 文件只是 I2C 子系统的接口。您可以发送 I2C 消息、接收 I2C 消息并使用相应的 write()read()ioctl() 系统调用配置 I2C。一旦您对 /dev/i2c-1 文件执行这些操作之一,它就会通过 Virtual file system to I2C layer, where those operations are implemented. Actual callbacks for those operations are implemented in drivers/i2c/i2c-dev.c file, more specifically -- in i2cdev_fops 结构传递。

例如,当您对 /dev/i2c-1 文件执行 open() 系统调用时,内核中会调用 i2cdev_open() 函数,这会为进一步的 [=86] 创建 i2c_client 结构=] 操作,并且该结构被分配给文件的私有数据字段:

/* This creates an anonymous i2c_client, which may later be
 * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
 *
 * This client is ** NEVER REGISTERED ** with the driver model
 * or I2C core code!!  It just holds private copies of addressing
 * information and maybe a PEC flag.
 */
client = kzalloc(sizeof(*client), GFP_KERNEL);
...
file->private_data = client;

当你接下来对该/dev/i2c-1文件进行一些操作时,i2c_client结构将从file->private_data字段中提取出来,并为该结构调用相应的函数。

对于 write() 系统调用,将调用 i2cdev_write() 函数,这将导致 i2c_master_send() 函数调用:

struct i2c_client *client = file->private_data;
...
ret = i2c_master_send(client, tmp, count);

以同样的方式 read() 导致 i2cdev_read(),从而导致 i2c_master_recv()。而 ioctl() 导致 i2cdev_ioctl(),它只是将相应的标志分配给 i2c_client 结构。

/dev/i2c-1 如何与硬件 I2C 驱动程序相关联

/dev/i2c-* 文件执行的操作最终导致执行 I2C 硬件驱动程序函数。让我们看一个例子。当我们进行 write() 系统调用时,整个链将是:

write() -> i2cdev_write() -> i2c_master_send() -> i2c_transfer() -> __i2c_transfer() -> adap->algo->master_xfer(),其中 adapi2c_adapter 结构,它存储有关 I2C 控制器的硬件特定数据,例如 I2C 硬件驱动程序的回调。 .master_xfer 回调是在 I2C 硬件驱动程序中实现的。例如,对于 OMAP 平台,它在 drivers/i2c/busses/i2c-omap.c file, see omap_i2c_xfer() 函数中实现。