1. 历史背景
为了让读者在整体上对SylixOS SD 协议栈(以下称作SD Stack)有更深的理解,本篇将会把早期SD Stack与最新的进行对比说明。第一版本始于2010年,该版仅支持SD存储卡(SD Memory),同时支持SPI和SD传输模式。后来由于项目需求,需要支持SDIO WIFI设备,这就带来了多设备类支持的需求。原SD Stack 在这方面并未有相应的功能,并且存在诸多不足或缺陷,因此需要一个更加丰富和完善的SD Stack。
2. 原有SD Stack分析
2.1 原有SD Stack功能
libsylixos 1.0.0-rc43及以前的版本SD Stack 结构如图 2.1所示:
Host层:硬件控制器抽象层,SD控制器在不同的硬件平台上可能有不同的实现,因此需要实现具体的传输处理操作。所有的控制器驱动都向上(Core层)提供统一的操作接口。SD Stack已经提供了符合SD规范的标准控制器SDHCI驱动, 在此情况下,控制器驱动的编写将更加简单。当然也可使用SPI传输。
Core层:主要封装了SD和SPI两种传输方式,让Client层只需要关心与具体设备相关的SD协议处理,而不必考虑底层的硬件情况。Core层同时还提供相关工具库供Client使用,sdLib为基于Core Xfer 为传输对象封装的SD Memory相关协议操作库。
Client层:实现具体的设备类协议。SD Memory 负责SD Memory 相关的协议处理(如初始化,块读写等),它同时完成与SylixOS块设备相关的接口创建(BLK_DEV)。
2.2 原有SD Stack存在的不足
原SD Stack虽然对SD协议进行了分层设计,较好的实现了设备类驱动和控制器驱动的分离,但由于最初设计时,其总线传输模型参考自SylixOS中I2C、SPI总线模型的设计,未考虑到SD总线自身的特殊性,存在许多不足:
-
Host与Client并未完全隔离
在新的硬件平台上要实现SD Memory的功能,驱动编写人员不仅要实现控制器驱动,还要负责SD Memory设备的创建/删除工作,这样极大的增加了SD驱动开发的复杂度,比如创建SD Memory,需要了解SylixOS是如何挂载块设备的,期间还要保存许多设备参数,以便在设备删除时使用。理论上讲,SD Memory是一独立的设备类驱动,编写底层硬件驱动的人员无需关心,仅仅需要的是完成与硬件相关的处理(传输、设备插入/拔出中断处理等)。
-
没有良好的设备类管理机制
假设现在增加了一个设备类驱动,当插入一个SD设备时,如何正确的找到对应的设备类驱动并创建对应的设备?在现有基础上,SD驱动编写人员需要增加对此设备的创建工作,由于各个设备类驱动是相互松散的,就得一个一个的尝试,并且还需要对SD协议本身有比较好的了解,才能完成此工作。更糟糕的是,每增加一个设备类驱动,Host驱动都需要随之修改(这意味着所有已经发布的BSP包里面的SD驱动都需要修改,其缺点是显而易见的)。 -
Client依赖Host某些特征
原有SD Stack创建一个SD Memory设备时,还需要提供Host的一些信息,如在SPI模式下时, Host使用的片选信号等。理论上,设备类驱动本无需这些信息,应该由SD Stack本身负责处理。
为什么会存在这些不足?
前面说过,SD总线传输模型参考了I2C、SPI的设计,既然都是总线,那应该也能满足需求的。产生这些不足,原因有以下两点:
-
I2C、SPI总线上的所有设备在数据传输上均表现一致,并未有更多与具体应用相关的特殊协议,实际上这些设备都可以看做一类;SD总线上可能存在有不同应用协议的设备,仅仅提供总线传输不能有效的管理这些设备类。
-
更重要的,I2C、SPI上的设备通常不是热插拔的,也就是说,针对具体硬件平台,驱动编写人员事先已经知道了总线上已经存在何种设备了,可以编写特定的驱动程序,它是静态的。而SD设备是热插拔的,SD总线上,可能在不同的时候存在不同类的SD设备,如果没有一个良好的类驱动的管理,就相当于把这些工作抛给驱动编写人员了。
3. 新的 SD Stack
针对上面所述的原有SD Stack存在的问题,在着手编写程序之前,定下了以下目标:
-
增加SDIO对协议支持,并能为SDIO设备提供良好的驱动管理,各个SDIO设备驱动的开发应该相互独立。
-
完全隔离Client层和Host层,使两者的开发相互独立Client层无需Host层的任何信息,仅仅处理具体应用协议。Host层仅仅处理硬件传输相关的工作。
-
协议栈本身负责设备驱动管理,自动完成设备的驱动匹配并动态创建、删除设备工作等。
-
最好能兼容旧的SD 控制器驱动。
围绕以上几点目标,新的SD Stack结构如图 3.1所示。
对比图 2.1,增加了对sdio的支持,同时增加SDM模块。新SD Stack并未改变原来的整体结构,因此,可以完全兼容旧的SD驱动。
sdioLib: 与sdLib一样,是针对sdio设备特殊操作的相关工具库,sdio设备驱动使用此库可以使驱动的编写更简单。
SDIO BASE: sdio基础驱动,它和SD Memory处于同一级别,它不会直接去创建实际的sdio设备,主要是在完成sdio的基础初始化后,使用特定的sdio子类驱动来创建对应的设备。之所以设计sdio基础驱动,是为了让驱动的管理更加统一,同时将原设计中的一些缺点(比如设备驱动要关心Host的一些信息)掩藏起来, 让sdio设备驱动开发更简洁。
SDM: SD DRV Manager, 即SD 驱动管理层,这里的SD驱动包括SD Client驱动和Host驱动,这样两者的信息都由SDM管理维护,以此达到两者完全隔离的目的。