做教育app的网站有哪些,搜索引擎营销的基本方法,西安网页设计培训机构哪个好,江西加油app下载官网本来想着i2c和spi是一样的#xff0c;标题都想抄袭成《rtt设备驱动框架学习-i2c总线和设备》#xff0c;然后看过源码发现#xff0c;i2c没有分开总线和设备#xff0c;我想着正常它和spi一样有总线和设备#xff0c;设备存在竞争。估计是因为i2c设备可以通过i2c地址区分标题都想抄袭成《rtt设备驱动框架学习-i2c总线和设备》然后看过源码发现i2c没有分开总线和设备我想着正常它和spi一样有总线和设备设备存在竞争。估计是因为i2c设备可以通过i2c地址区分所以不需要来个i2c设备了吧。
1.i2c总线
i2c总线分为硬件i2c总线和软件模拟i2c总线。 按照面向对象的思想要抽象出硬件i2c总线和软件i2c总线的相同点和不同点。相同点就变成了i2c总线基类不同点就是各个子类的私有特性。
rtt就是这么干的共同点是什么方法——都得有配置方法和数据传输方法等于是抽象出了i2c的方法: struct rt_i2c_bus_device_ops { rt_ssize_t (*master_xfer)(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num); rt_ssize_t (*slave_xfer)(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num); rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus, int cmd, void *args);};
抽象出3个公共方法主设备通信接口从设备通信接口和控制方法。
然后作为成员组成rt_i2c_bus_device类: i2c.h中 struct rt_i2c_bus_device { struct rt_device parent; const struct rt_i2c_bus_device_ops *ops; rt_uint16_t flags; struct rt_mutex lock; rt_uint32_t timeout; rt_uint32_t retries; void *priv; };
缺图对象图ops展开方法用纯虚方法表示或者指针但ops展开后成为一个个纯虚方法更为贴切。
1.1硬件i2c
对于硬件i2c子类则通过调用硬件sdk来实现rt_spi_bus的ops操作方法实现完美闭环。
缺图对象图ops展开的一个个方法用虚方法表示或者普通方法即可意味着重写父类方法。
1.2 软件i2c总线
对于软件i2c总线共同点就是软件gpio也要实现上面3个公共方法差异点就是要用gpio模拟硬件i2c的2线通信接口——抽象出软件i2c通信接口。因为i2c通信时序是共同的如果放到驱动层每个bsp都要实现一样逻辑的通信函数——重复造轮子——对于这种“重复”性的就抽象出来放到上层最合理。——就此我也知道了在c中什么时候需要虚函数/纯虚函数那要看下层有没有共性的东西。
至于i2c软总线通信接口的实现需要哪些信息rtt抽象出来的如下: i2c-bit-ops.h 中 struct rt_i2c_bit_ops { void data; / private data for lowlevel routines */ void (*set_sda)(void *data, rt_int32_t state); void (*set_scl)(void *data, rt_int32_t state); rt_int32_t (*get_sda)(void *data); rt_int32_t (*get_scl)(void *data); void (udelay)(rt_uint32_t us); rt_uint32_t delay_us; / scl and sda line delay / rt_uint32_t timeout; / in tick */ };
为何如此抽象i2c通信就用到2线所以只要提供操作2线的高低电平接口即可控制通信了其时序是共通的再加上延时即可完成硬件无关的i2c通信时序所以差异点在于操作硬件高低电平的函数延时函数等的实现不同于是把它们抽象出来。
模拟通信接口的方法在i2c-bit-ops.c中从该c中可以看到它只提供了i2c主设备通信其他两个i2c公共方法从设备通信和控制方法均没有支持。待开发。另外在i2c-bit-ops.c中可以看到i2c通信硬件无关的时序接口要真正驱动引脚还得实现struct rt_i2c_bit_ops的接口。
为何还要抽象出来同样的下面还有个子类——具体硬件厂家的软件i2c总线——因为各个硬件操作gpio具体实现是不同的但是这些方法是都一样所以抽象出来——跨硬件平台这个框架才叫框架这个框架才有意义。
rtt的h文件中没有关于抽象出的i2c软总线类不过可以参考它的soft_i2c.c中抽象出i2c软总线类:
struct rt_soft_i2c { struct rt_i2c_bus_device i2c_bus; struct rt_i2c_bit_ops ops; }; 就是继承i2c总线类后软件i2c通信接口方法。
soft_i2c.c中的实现自洽的啥叫自洽就是它用到了pin设备如果该bsp实现了pin框架对接那么soft_i2c.c就完成了整个的软件i2c配置只需要开启宏和定义下软件i2c引脚就行了不需要bsp再进行创建软件i2c总线设备了。不过也可以只要名字不一样也可以不过结果一样以我看来有pin对接就不要在bsp层重复实现了。
如果没有实现pin设备框架对接那么就需要bsp驱动层实现软总线各个厂家bsp创建各自的软i2c总线子类对象实现软件i2c的ops方法即可。
缺图对象图 1bus—ops展开的一个个方法用虚方法表示或者普通方法即可意味着重写父类i2c总线基类的方法。 2软i2c总线子类的ops展开的一个个方法用纯虚方法表示或者指针但ops展开后成为一个个纯虚方法更为贴切。
/ components / drivers / i2c下有4个文件: i2c-bit-ops.c i2c_core.c i2c_dev.c soft_i2c.c 这4个文件的关系: i2c_dev.c是重写/实现rt_device基类的方法的文件也是初始化i2c基类的接口所在rt_i2c_bus_device_device_init。
i2c_core.c是中转站/中间人因为i2c_dev.c中重写设备基类的方法这些方法里调用了i2c_core.c提供的方法如rt_i2c_transfer而i2c_core.c中这些方法比如 rt_i2c_transfer实现内部是调用的i2c的3个公共方法比如bus-ops-master_xfer而这3个公共方法对于硬件i2c总线则走硬件总线的实现对于软件模拟i2c总线则走i2c-bit-ops.c中的方法比如i2c_bit_xfer前面知道i2c-bit-ops.c中只实现了主设备通信即只有i2c_bit_xfer。以此来看i2c_core.c可不就是中间人/岔路口/分发站/跳转点么 而i2c_bit_xfer函数里使用到i2c软总线抽象的那些延时2线高低电平接口而这些接口可以是bsp的驱动层实现的也可以是soft_i2c.c里实现的——通过pin设备框架控制2线高低电平当然还需要实现us延时函数。
而soft_i2c.c是对于支持pin设备的bsp的软总线实现实例它已自洽的不需要bsp再重复造轮子了。而它则可以作为参照对于没有支持pin和延时函数的bsp实现软总线的参考例子。它通过pin设备实现了软i2c总线的模拟接口这样i2c-bit-ops.c中通信方法调用2线控制电平和延迟函数就有了落脚点。而pin设备就需要驱动层的gpio驱动支持的gpio驱动就调用了硬件sdk自然能驱动硬件引脚。这样屏蔽了硬件差异实现跨硬件平台。
2.i2c设备
无。通过i2c从机地址就能区分i2c设备就没有必要专门搞个设备累了多余了。
3.使用
官方文档说的就是如何使用的i2c总线而上面学的是注册/初始化/构造流程。