PCI总线基础知识和SylixOS下PCI设备驱动框架介绍

一、PCI总线基础知识
1、PCI总线的概念
            PCI是 Peripheral Component Interconnect(外设部件互联 )的缩写,它是CPU和外围设备通信的高速传输总线。PCI总线的工作频率一般为33MHz(有的PCI总线工作频率为64MHz和132MHz),是一种同步的独立于处理器的32位或64位局部总线。
2、PCI总线结构
       PCI总线是一种树型结构 ,并且独立于CPU总线,可以和CPU总线并行操作。PCI总线上可以挂接PCI设备和PCI桥片,PCI总线上只允许有一个PCI主设备,其他的均为PCI 从设备,而且读写操作只能在主从设备之间进行,从设备之间的数据交换需要通过主设备中转。 PCI总线结构如下图所示。

20171012《PCI总线结构图》.png (20.47 KB, 下载次数: 0)

下载附件

2017-10-12 15:21 上传


图1-1  PCI总线结构图

3、PCI总线和PCI总线树

       1个或者多个有血缘关系的PCI总线组成一颗PCi总线树。PCI总线由Host主桥或者PCI桥管理,PCI通过PCI桥扩展PCI总线,与Host主桥直接相连的PCI总线通常被命名为PCI总线0。一个处理器系统可能拥有多个Host主桥,有几个Host主桥就有几颗PCI总线树。

4、PCI总线的特点

      (1) 传输速率高最大数据传输率为132MB/s,当数据宽度升级到64位,数据传输率可达264MB/s。这是其他总线难以比拟的。 它大大缓解了数据I/O瓶颈,使高性能CPU的功能得以充分发挥,适应高速设备数据传输的需要。

       (2) 多总线共存采用PCI总线可在一个系统中让多种总线共存,容纳不同速度的设备一起工作。

       (3) 独立于CPU PCI总线不依附于某一具体处理器,兼容性好。

       (4) 自动识别与配置外设,用户使用方便。

       (5)并行操作能力,可与CPU并行执行。

       (6)PCI总线上所有时序的产生和控制均由主设备发起。

       (7)PCI总线的地址总线和数据总线是分时复用的。(优点:1、节省插件的管脚数量;2、便于突发数据传输,即一个地址后面跟大量数据)

二、 SylixOS下PCI设备驱动框架介绍
        从本质上讲PCI只是一种总线,具体的PCI设备可以是字符设备、网络设备、USB主机控制器等,因此,一个通过PCI总线与系统连接的设备的驱动至少包含PCI驱动和设备本身驱动两部分内容。PCI驱动只是为了辅助设备本身的驱动,它不是目的,而是手段。例如 ,对于通过PCI总线与系统连接的字符设备,则驱动中除了要实现PCI驱动部分外,其主体仍然是设备作为字符设备的本身驱动,即实现file_operations成员函数并将设备注册进内核。

        在SylixOS中,用PCI_DRV_CB结构体来定义PCI驱动,该结构体包含PCI设备的探测/移除、挂起/恢复等函数,其定义代码如下代码清单所示。 PCI_DRV_CB结构体和I2C的 LW_I2C_DEVICE结构体、SPI的 LW_SPI_DEVICE结构体的非常相似,都是起到挂接总线的作用。
  1. /*********************************************************************************************************
  2.   驱动控制块
  3. *********************************************************************************************************/
  4. typedef struct {
  5.     LW_LIST_LINE            PCIDRV_lineDrvNode;                         /* 驱动节点管理                 */
  6.     CHAR                    PCIDRV_cDrvName[PCI_DRV_NAME_MAX];          /* 驱动名称                     */
  7.     PVOID                   PCIDRV_pvPriv;                              /* 私有数据                     */
  8.     PCI_DEV_ID_HANDLE       PCIDRV_hDrvIdTable;                         /* 设备支持列表                 */
  9.     UINT32                  PCIDRV_uiDrvIdTableSize;                    /* 设备支持列表大小             */

  10.     /*
  11.      *  驱动常用函数, PCIDRV_pfuncDevProbe 与 PCIDRV_pfuncDevRemove 不能为 LW_NULL, 其它可选
  12.      */
  13.     INT   (*PCIDRV_pfuncDevProbe)(PCI_DEV_HANDLE hHandle, const PCI_DEV_ID_HANDLE hIdEntry);
  14.     VOID  (*PCIDRV_pfuncDevRemove)(PCI_DEV_HANDLE hHandle);
  15.     INT   (*PCIDRV_pfuncDevSuspend)(PCI_DEV_HANDLE hHandle, PCI_PM_MESSAGE_HANDLE hPmMsg);
  16.     INT   (*PCIDRV_pfuncDevSuspendLate)(PCI_DEV_HANDLE hHandle, PCI_PM_MESSAGE_HANDLE hPmMsg);
  17.     INT   (*PCIDRV_pfuncDevResumeEarly)(PCI_DEV_HANDLE hHandle);
  18.     INT   (*PCIDRV_pfuncDevResume)(PCI_DEV_HANDLE hHandle);
  19.     VOID  (*PCIDRV_pfuncDevShutdown)(PCI_DEV_HANDLE hHandle);

  20.     PCI_ERROR_HANDLE        PCIDRV_hDrvErrHandler;                      /* 错误处理句柄                 */

  21.     INT                     PCIDRV_iDrvFlag;                            /* 驱动标志                     */
  22.     UINT32                  PCIDRV_uiDrvDevNum;                         /* 关联设备数                   */
  23.     LW_LIST_LINE_HEADER     PCIDRV_plineDrvDevHeader;                   /* 设备管理链表头               */
  24. } PCI_DRV_CB;
  25. typedef PCI_DRV_CB         *PCI_DRV_HANDLE;
复制代码
        PCI_DRV_CB结构体的 PCIDRV_pfuncDevProbe函数指针指向的probe函数,需要完成PCI设备的初始化及其设备本身自身(字符、TTY、网络等)驱动的注册。在SylixOS的probe函数中,首先会通过PCI总线获得PCI设备的基本资源,如:设备的起始地址、资源大小、中断等,获得资源之后,剩下的就是利用获得的资源编写设备本身自身的驱动代码(基本和编写非PCI总线上的设备驱动没啥区别)。 当PCI设备驱动完成后,在PCI设备数据传输时,是经过PCI总线传给CPU的,这和Nor Flash挂接在SPI总线上,通过SPI和CPU通信的机制一样。         以上就是我学习PCI总线的总结,若是有总结的不对的地方,烦请各位指正。

你可能感兴趣的:(SylixOS,PCI总线)