在之前分析mdio子系统时,我们提到系统实现了fixed-mii_bus,从而为mac2mac提供虚拟mii_bus和虚拟phy_device,实现对虚拟phy_device的模拟。受此启发,我打算实现一个虚拟的i2c adapter,并基于该i2c adapter挂载一个虚拟的i2c device,并基于虚拟i2c adapter、i2c device搭建一个虚拟的i2c controller即i2c设备,以便为需要学习linux i2c驱动模型的童鞋可以方便的练习i2c device driver。
本篇文章的目的如下:
- 当你没有开发板,又想学习i2c驱动模型,并想进行linux i2c device driver的练习时;
- 当你完成了i2c device driver,在硬件开发板出来之前进行i2c device driver的验证时。
若对linux i2c驱动模型不熟悉时,可参考我之前写的文章:
一、 virtual i2c adapter的实现分析
我们知道linux系统针对i2c controller抽象了数据结构i2c_adapter,因此我们在进行虚拟i2c
controller的实现,也就是实现一个i2c_adapter类型的变量,并将其注册至i2c子系统中。
数据结构定义及关联
因我们需要模拟的是一个虚拟的i2c controller,以及多个依附于虚拟i2c controller的i2c
device,所以我们定义而定数据结构包含i2c controller、i2c device两部分的内容。
我们定义了数据结构体virtual_i2c_bus_t,该结构体中包含了i2c_adapter类型的成员和virtual_i2c_adapter_info_t类型的成员,其中:
- i2c_adapter类型的成员中,我们需要实现i2c_adapter->algo,因我们抽象的是i2c ,因此我们需要实现master_xfer接口和functionality接口;
- 而virtual_i2c_adapter_info_t结构体则主要包含了一个双向链表头list,和一个互斥量。list链表用于将所有虚拟i2c设备连接在一起,虚拟i2c设备对应的数据结构为virtual_i2c_dev_info_t,该数据结构包括node节点、virtual i2c device的地址addr,virtual i2c device对应的寄存器等。
如下即为virtual_i2c_bus_t、virtual_i2c_adapter_info_t、virtual_i2c_dev_info_t、
i2c_adapter、i2c_algorithm数据结构之间的关联图。而我们在virtual i2c controller的probe接口中,即是用来实现这些数据结构之间的关联,从而织成如下的关联图。
如下即为virtual_i2c_bus_t、virtual_i2c_adapter_info_t、virtual_i2c_dev_info_t的定义。
二、virtual controller driver实现流程说明
针对virtual controller driver的实现,主要包括如下几个步骤(我们还是借助platform驱动模型实现virtual controller driver):
- 创建一个platform device,用于实现与virtual controller driver对应的platform driver进行匹配;
- 创建一个platform driver,在该driver的probe接口中实现如下功能:
- 申请virtual_i2c_bus_t类型的内存空间,并设置virtual_i2c_bus_t->adapter.algo,主要设置master_xfer(virtual_i2c_master_xfer)、functionality;
- 调用i2c_add_adapter接口,将virtual_i2c_bus_t->adapter注册至i2c子系统中;
- 调用i2c_new_device接口,创建virtual i2c device,并依附于上述a中创建的adapter;
- 针对接口virtual_i2c_master_xfer,针对传递i2c_msg,将其与已注册至virtual_i2c_bus_t->virtual_dev_info中的virtual i2c device进行对比,若找到i2c 地址相同的virtual i2c device,则进行寄存器的设置/读取寄存器的值等。
三、 i2c device driver的实现流程说明
通过以上两步已经实现了virtual i2c adapter、virtual i2c device,现在我们就可以实现i2c
device driver,进行i2c device driver的联系了。实现的流程如下:
- 定义struct i2c_driver类型的变量,并实现 struct i2c_device_id、struct of_device_id类型变量的设置,并赋值给struct i2c_driver中对应的成员变量;并实现struct i2c_driver中的probe接口、remove接口;
- 在上述1中实现的probe接口中,我们可以实现该i2c device对应的字符设备,从而应用程序即可通过操作字符设备文件,从而完成与virtual i2c device的通信。
四、i2c device字符设备文件的访问
当完成以上内容后,我们即可以在应用层中,通过访问字符设备文件,从而完成与virtual i2c device的访问。
本文主要简要说明了virtual i2c controller、virtual i2c device的实现,用于进行i2c模块的练习(尤其在身边没有开发板,又想学习linux i2c驱动时),至于本章的代码,已经上传至csdn上,稍后会把链接发送出来(链接如下virtual i2c controller driver)。