rtt设备驱动框架学习-spi总线和设备

1.spi总线
spi总线分为硬件spi总线和软件模拟spi总线。
按照面向对象的思想,要抽象出硬件spi总线和软件spi总线的相同点和不同点。相同点就变成了spi总线基类,不同点就是各个子类的私有特性。

rtt就是这么干的,共同点是什么?方法——都得有spi配置方法和数据传输方法等,于是抽象出了rt_spi_bus类。
struct rt_spi_bus
{ struct rt_device parent; rt_uint8_t mode; const struct rt_spi_ops *ops; struct rt_mutex lock; struct rt_spi_device *owner;};

对于硬件spi子类,则负责实现rt_spi_bus的ops操作方法。

对于软件spi,差异点就是要用gpio模拟硬件spi的4线或3线通信,那么软件gpio除了实现上面共同点ops操作方法外,还得抽象软件spi通信。
于是抽象出spi软总线基类——rt_spi_bit_obj。
struct rt_spi_bit_obj
{ struct rt_spi_bus bus; struct rt_spi_bit_ops *ops; struct rt_spi_configuration config;};

因为有共同点所以得继承rt_spi_bus基类,它的差异点抽象出了rt_spi_bit_ops操作方法实现gpio模拟spi通信。

struct rt_spi_bit_ops
{ void data; / private data for lowlevel routines */ void (*const tog_sclk)(void *data); void (*const set_sclk)(void *data, rt_int32_t state); void (*const set_mosi)(void *data, rt_int32_t state); void (*const set_miso)(void *data, rt_int32_t state); rt_int32_t (*const get_sclk)(void *data); rt_int32_t (*const get_mosi)(void *data); rt_int32_t (*const get_miso)(void *data); void (*const dir_mosi)(void *data, rt_int32_t state); void (*const dir_miso)(void *data, rt_int32_t state); void (const udelay)(rt_uint32_t us); rt_uint32_t delay_us; / sclk, mosi and miso line delay */};

这个抽象出的方法作为软件spi总线类rt_spi_bit_obj的成员,为何还要抽象出来?因为下面还有个子类——具体硬件厂家的软件spi总线——因为各个硬件操作gpio具体实现是不同的,但是这些方法是都一样,所以抽象出来——跨硬件平台,这个框架才叫框架,这个框架才有意义。
接着就是硬件spi软总线层次了,各个厂家bsp创建各自的软spi总线子类对象,实现软件spi基类的ops方法。

2.spi设备
上面spi总线基类里有个“struct rt_spi_device *owner”,这是spi设备对象指针,为何在spi总线里加个spi设备的指针成员,且还叫owner(字面意思:spi总线持有者或霸占者或拥有者)?
用面向对象的思想来分析下,spi总线和spi设备是啥关系?可以搜下面向对象思想中对象关系有哪些,有包含(拥有)关系,聚合关系,关联关系等等。而spi总线和spi设备就是关联关系吧。谁关联谁?我觉得是互相关联吧。你看,它们的关系特点:一个spi总线上可以挂载很多个spi设备,同一时刻,一个spi总线只能和一个spi设备通信,这样看来同一个spi总线上的spi设备是分时共享这个spi总线的,spi设备之间是有竞争关系的,spi总线就相当于共享资源,同一时刻只能有一个spi设备霸占。所以上面抽象出的spi总线基类里有一个owner标志,表示当前是哪个spi设备在使用/霸占/持有spi总线。
那么同样的,spi设备里肯定也有一个指针指向它挂载到那个spi总线上了——因为它们是关联关系。
于是看下rtt抽象出的spi设备类rt_spi_device定义:
struct rt_spi_device
{ struct rt_device parent; struct rt_spi_bus *bus; struct rt_spi_configuration config; rt_base_t cs_pin; void *user_data;};

果然不出所料,有个spi总线基类指针来表明该spi设备挂载到哪个spi总线上了。

你可能感兴趣的:(rt-thread,学习)