我已经在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驱动程序(读/写)(并使用文件句柄读取如上所述)。
此实现是否独立于i2c模块?我只在运行modprobe i2c_dev后验证我可以看到我的代码正在运行。 modprobe i2c_dev加载i2c模块并在/ dev目录中形成/ dev / i2c-1,因为我已将i2c设备连接到它。
答案 0 :(得分:1)
I2C子系统的用户空间接口通过/dev/i2c-*
文件提供,并记录在Documentation/i2c/dev-interface。有两种方法可以发送I2C消息:
write()
发送普通缓冲区;您需要为此i2c_msg
ioctl()
请求发送I2C_RDWR
结构;您需要为此有关示例,请参阅this question。
/dev/i2c-1
文件只是I2C子系统的接口。您可以使用相应的write()
,read()
和ioctl()
系统调用发送I2C消息,接收I2C消息并配置I2C。在/dev/i2c-1
文件上执行这些操作之一后,它将通过Virtual file system传递到I2C层,在那里实现这些操作。这些操作的实际回调在drivers/i2c/i2c-dev.c文件中实现,更具体地说,在i2cdev_fops结构中实现。
例如,当您在open()
文件上执行/dev/i2c-1
系统调用时,将在内核中调用i2cdev_open()函数,该函数会为进一步的发送/接收操作创建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-*
文件执行的操作最终导致执行I2C硬件驱动程序功能。让我们看一个例子吧。当我们进行write()
系统调用时,整个链将是:
write()
- &gt; i2cdev_write()
- &gt; i2c_master_send()
- &gt; i2c_transfer()
- &gt; __i2c_transfer()
- &gt; adap->algo->master_xfer()
,其中adap
是i2c_adapter
结构,存储有关I2C控制器的硬件特定数据,例如I2C硬件驱动程序的回调。 .master_xfer
回调是在I2C硬件驱动程序中实现的。例如,对于OMAP平台,它在drivers/i2c/busses/i2c-omap.c文件中实现,请参阅omap_i2c_xfer()函数。