Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57155
  • 博文数量: 8
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-19 10:45
个人简介

分享笔者从事嵌入式工作几年来在Linux, SylixOS等操作系统中关于内核、驱动框架以及各种中间件开发和设计的技术。

文章分类
文章存档

2015年(8)

我的朋友

分类: 嵌入式

2015-07-10 09:46:13

1. 文件结构

       前面的两篇文章分别介绍了SD协议以及SylixOS SD协议栈的整体设计结构,在接下来将主要分析软件设计上的细节。为了让读者能够更方便的对照源码进行分析,这里首先简要介绍一下SD软件的文件结构。


    
       图1.1 SD协议栈文件结构
       以上文件位于SylixOS/system/device目录下,该目录下为SylixOS所有设备驱动框架的源代码。名为sd目录下的文件为对SD总线传输协议的抽象和封装,即本篇将要介绍的SD总线适配器。在sd的同一目录下,还有一个名为spi的文件夹,它是spi总线适配器,两者处于同一个层次。当一个SD设备工作于SD总线时,就使用SD总线适配器进行传输,当工作于SPI总线时,就使用SPI总线适配器进行传输。SD协议栈内部会根据注册的控制器驱动类型,自动选择对应的适配器,无需应用层考虑。目录sdcard即为整个SD协议栈的实现,它的结构正如上一篇中图2.1所展示的一样,各层的意思请参考上一篇的介绍。host层已经提供了标准控制器SDHCI的驱动,对于其他硬件平台的控制器驱动,由于没有固定的标准,因此不放在SylixOS系统源码里,通常位于具体的BSP包驱动里面。另外,这里的SDSPI总线适配器就是上一篇图2.1中的HOST层所示的SD IFSPI IFIF interface)。include目录下的sdcardLib.h包含了sdcard所有头文件的引用,sddebug.h提供了sdcard组件的调试信息打印开关,方便在调试应用驱动或控制器驱动的时候打印内部信息。


2. 适配器的功能和特点

适配器(adapter),在硬件中我们通常可理解为它是一个接口转换器,如我们常见的电源适配器,包括显示器电源适配器、手机电源适配器等,它们都是将市电(220V)电压转换为对应设备需要的特定工作电压,同时为了让两者能够连接起来,都必然提供了连接两者的硬件接口。软件上所说的适配器也有相同的特征,即接口转换。

不过,软件里的适配器根据其目的不同,可以扩展更多的含义,如我们所知的设计模式里的适配器模式,它强调的是通过接口转换(或者说是功能转换)以达到让原本不兼容的组件能够工作在一起,这种转换并不局限于封装并改变原有的接口,也可能是增加新的功能接口以适应新的需求,它的主要目的是复用和兼容;而有的适配器是为可预见的变化提供一套统一的操作接口标准,它的主要目的是提高适应性和组件之间的隔离。这些特点并不是绝对独立的,只是说它们可能偏向于不同的目的。

 

3. SD总线适配器的实现

SD总线适配器的功能更偏向于上面所讲的后者,即为SD总线传输定义一套统一的操作接口标准。该标准不是随意定的,而是根据SD物理层协议定义的,同时考虑各种硬件控制器不同的特点而抽象出来的。前面所说了,所有的适配器都有一个共同的特点,即充当转换工作,因此,软件上必须为转换双方提供相应的操作接口。对于SD总线适配器,同样提供了两类接口,即供SD设备向硬件提交传输请求的接口和相应的数据结构,供SD控制器如何接受并处理来自设备的请求的接口和相应的数据结构。下面对其进行分别介绍。

 

3.1      控制器接口

sd/sdBus.h里定义了一个如下的结构,用以描述(或者说是抽象)所有SD控制器的行为。

  1. struct lw_sd_device;
  2. typedef struct lw_sd_funcs {
  3.     INT (*SDFUNC_pfuncMasterXfer)(PLW_SD_ADAPTER       psdadapter,
  4.                                   struct lw_sd_device *psddevice,
  5.                                   PLW_SD_MESSAGE       psdmsg,
  6.                                   INT iNum);
  7.     INT (*SDFUNC_pfuncMasterCtl)(PLW_SD_ADAPTER   psdadapter,
  8.                                  INT              iCmd,
  9.                                  LONG             lArg);
  10. } LW_SD_FUNCS, *PLW_SD_FUNCS;

    从上面的函数指针命名中带有master这个单词可以看出,这是对控制器的描述(因为SD总线为一个主从总线,控制器端称为主,设备端称为从)。SDFUNC_pfuncMasterXfer控制器实现设备提交的传输请求,SDFUNC_pfuncMasterCtl实现设备提交的与控制器硬件本身息息相关的控制请求。这些请求包括打开/关闭控制器的电源,设置控制器的数据位宽,设置时钟频率等。PLW_SD_MESSAGE描述了一个SD请求(一个请求就是一次会话)的格式,它是设备与控制器交互的最重要的信息。一个SD控制器通过以下函数(位于sd/sdDev.h)产生对应的实体对象:

  1. INT API_SdAdapterCreate(CPCHAR pcName, PLW_SD_FUNCS psdfunc);


3.2      设备接口

应用层通过一个抽象SD设备对象与SD控制器通信,创建该对象的API(位于sd/sdDev.h如下:

  1. PLW_SD_DEVICE API_SdDeviceCreate(CPCHAR pcAdapterName, CPCHAR pcDeviceName);

PLW_SD_DEVICE即为一个SD设备的抽象,从上面API的参数可知,一个SD设备必然关联到一个SD适配器。应用层通过以下APISD控制器提交传输控制请求:

  1. INT API_SdDeviceTransfer(PLW_SD_DEVICE  psddevice,
  2.                          PLW_SD_MESSAGE psdmsg,
  3.                          INT            iNum);
  4. INT API_SdDeviceCtl(PLW_SD_DEVICE       psddevice,
  5.                     INT                 iCmd,
  6.                     LONG                lArg);

    上面两个函数为整个SD协议完成底层传输控制的唯一接口。

    最后需要说明的是,本篇不会讲解各个数据结构或API的详细含义及注意事项,因为本篇(包括后面的几篇)的主要目的都是为了通过讲解软件结构让读者能够在阅读源码的时候,能够知道对应模块的作用、所在的层次,以达到从全局认识的目的。在最后的几篇介绍如何编写SD应用驱动和控制器驱动的文章中,将会有更详细的说明。

 

阅读(2551) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~