SylixOS_x86_PCI串口驱动浅析

1. 适用范围

    本文仅针对于3.0及上版本的SylixOS x86平台PCI转串口相关驱动架构进行简单的分析。

哈密网站制作公司哪家好,找成都创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设公司等网站项目制作,到程序开发,运营维护。成都创新互联2013年开创至今到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联

2. PCI简介

    外部链接标准(或称个人电脑界面,Personal Computer Interface),实际应用中简称为PCI(Peripheral Component Interconnect),是一种连接电脑主板和外部设备的总线标准。一般PCI装置可分为以下两种形式:

    直接内建于主板上的集成电路,在PCI规范中称作“嵌入装置”(planar device);或者安装在插槽上的扩充界面卡。

    PCI 总线见于现代的个人电脑中,并已取代了ISA和VESA局部总线,成为了标准扩充总线。PCI总线亦常见于其他电脑类型中。PCI总线最终将被PCI Express和其他更先进的技术取代,这些技术现在已经被用于最新款的电脑中。

    PCI规范规定了该总线的物理尺寸(包括线宽)、电气特性、总线时序和协议。该规范可从美国PCI-SIG协会购得。

    常见的PCI卡包括网络卡、声卡、调变解调器(调制解调器)、电视卡和硬盘控制器等,另外还有USB和串列埠等端口。原本显卡通常也是PCI装置,但很快其频宽已不足以支援显卡的性能。PCI显卡现在仅用在需要额外的外接显示器或主板上没有AGP和PCI Express槽的情况。

3. PCI串口卡简介

    串口卡主要是用来扩展PC的串口数量和种类。常见的x86机器主板上可能只有一个或者两个RS232的串口接口,在某些场景下不能满足对串口的需求,于是就有了PCI串口卡。通常PCI串口卡会支持拓展2至8个串口,也会支持RS232,RS485,RS422这几种串口格式。PCI串口卡在工业和军工领域运用广泛。

4. PCI串口驱动架构分析

4.1      SylixOS下一般的PCI驱动架构

    在x86的base工程libsylixos/SylixOS/driver/pci/null路径下,提供了SylixOS PCI驱动示例:pciNullDev.c。

        pciNullDev.c中主要实现了如表 41所示五个主体框架函数。

表 41  pciNullDev.c中主体函数

函数名函数功能
pciNullDevInitPCI设备驱动初始化
pciNullDevProbePCI设备ID探测和资源信息初始化
pciNullDevRemove删除PCI设备
pciNullDevIdTblGet获取PCI设备ID表的表头与表头大小
pciNullDevIsrPCI设备驱动中断服务程序
  • 函数pciNullDevInit

        该函数主要用来初始化PCI设备驱动,其调用pciNullDevIdTblGet等函数将相关的PCI设备结构体填充完成,并调用API_PciDrvRegister函数注册PCI设备驱动。

  • 函数pciNullDevProbe

        该函数由SylixOS PCI子系统回调,主要完成更新设备驱动版本信息,设备索引号,获取设备MEM、IO、IRQ等资源信息以及中断连接与使能操作。

  • 函数pciNullDevRemove

        该函数由SylixOS PCI子系统回调,主要完成删除PCI设备的一系列操作,在该示例中没有实现相关功能代码。

  • 函数pciNullDevIdTblGet

        该函数主要由pciNullDevInit函数调用,用来获取相关PCI设备的ID表的表头与表的大小。

  • 函数pciNullDevIsr

        该函数为驱动服务函数,主要提供了该PCI设备驱动的中断服务处理,在该示例中中断服务处理没有实现相关功能代码。

        pciNullDev.c示例中的PCI设备驱动的流程如图 41所示:

SylixOS_x86_PCI串口驱动浅析

图 41  pciNullDev.c设备驱动大致流程

4.2      SylixOS下PCI串口设备的驱动架构

    在x86的base工程libsylixos/SylixOS/driver/pci/sio路径存放的是PCI串口卡驱动。pciSioExar.c和pciSioNetmos.c均是PCI串口卡的驱动,是针对不同厂商的适配。一般PCI串口卡都是使用了16c500这一系列的串口芯片,这里着重分析pciSioNetmos.c。

4.2.1   PCI设备ID表

    如程序清单 41所示pciSioNetmos.c中有一个驱动支持的设备ID表结构体数组。PCI驱动通过PCI总线获取设备相关ID数据和驱动中的驱动支持设备ID表来匹配加载相关的驱动。

程序清单 41  驱动支持设备ID表

/*********************************************************************************************************
  驱动支持的设备 ID 表, 用于驱动与设备进行自动匹配, 与 Linux 参数保持一致.
*********************************************************************************************************/
staticconstPCI_DEV_ID_CB  pciSioNetmosIdTbl[] = {
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
        PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
        0xa000, 0x1000, 0, 0,
        netmos_9912
    },
    {
    }                                                                   /* terminatelist               */
}

    如程序清单 42,在x86的base工程libsylixos/SylixOS/system/drvice/pci/pciDrv.h中定义了设备ID表数据结构体PCI_DEV_ID_CB,其中包含厂商ID,设备ID,子厂商ID,子设备ID,设备类,设备子类,设备私有数据这7个相关属性,与Linux的PCI结构一致。

程序清单 42  驱动支持设备ID表结构体

/*********************************************************************************************************
  驱动支持设备列表控制块
*********************************************************************************************************/
typedefstruct {
    UINT32                  PCIDEVID_uiVendor;                          /* 厂商 ID                      */
    UINT32                  PCIDEVID_uiDevice;                          /* 设备 ID                      */
 
    UINT32                  PCIDEVID_uiSubVendor;                       /* 子厂商 ID                    */
    UINT32                  PCIDEVID_uiSubDevice;                       /* 子设备 ID                    */
 
    UINT32                  PCIDEVID_uiClass;                           /* 设备类                       */
    UINT32                  PCIDEVID_uiClassMask;                       /* 设备子类                     */
 
    ULONG                   PCIDEVID_ulData;                            /* 设备私有数据                 */
} PCI_DEV_ID_CB;

4.2.2   函数介绍

    如表 42所示在pciSioNetmos.c除了实现了和示例驱动中类似的Init、Probe、Remove、IdTblGet、Isr这五个相关类型的函数外,还实现了其他的设备相关驱动的函数。

表 4-2  pciSioNetmos.c实现的相关函数

函数名函数功能
pciSioNetmosInitPCI NETMOS 16c550 控制器驱动相关初始化
pciSioNetmosProbePCI NETMOS 16c550 板卡驱动探测设备
pciSioNetmosRemove总线上移除 PCI 设备
pciSioNetmosIdTblGet获取PCI设备ID表的表头与表头大小
pciSioNetmosChan创建一个 SIO 通道
pciSioNetmosIsrPCI设备驱动中断服务程序
pciSioNetmosGetReg获得 NETMOS 16C550 寄存器的值
pciSioNetmosGetReg设置 NETMOS 16C550 寄存器
  • 函数pciSioNetmosInit

        该函数和pciNullDevInit一样,调用pciNullDevIdTblGet获取驱动支持设备ID表的表头和大小,并设置驱动名为“pci_netmos”,pciSioNetmosProbe和pciSioNetmosRemove复制给PCI设备驱动控制块,调用API_PciDrvRegister函数注册PCI设备驱动。

  • 函数pciSioNetmosProbe

        该函数通过驱动设置的参数获取设备MEM的其实地址和MEM的大小,通过调用API_PciDevIoRemap重新映射驱动的内存空间地址,根据驱动设置的参数获取设备中断资源并注册,启动PCI总线的主模式,并调用pciSioNetmosChan函数来初始化串口设备的通道参数,最后通过ttyDevCreate函数创建出串口设备。

  • 函数pciSioNetmosRemove

        和函数pciNullDevRemove一样,实现总线上移除PCI设备时的处理,这里在pciSioNetmos.c里面没有实现相关方法。

  • 函数pciSioNetmosIdTblGet

        和pciNullDevIdTblGet一样,用来从驱动支持设备ID表中获取相关PCI设备的ID表的表头与表的大小。

  • 函数pciSioNetmosChan

        PCI串口驱动的关键函数,该函数将PCI设备驱动和串口设备驱动相互连接起来了。将驱动设置好的串口参数,PCI串口的中断和pciSioNetmosSetReg,pciSioNetmosGetReg函数赋值给PCI设备串口通道结构体,调用API_PciDevInterDisable先禁能PCI串口设备的中断,然后调用系统的16c550串口驱动中的sio16c550Init来初始化相关PCI串口通道,随后调用API_PciDevInterConnect,API_PciDevInterEnable连接并使能PCI串口设备中断,完成PCI串口通道的创建。

  • 函数pciSioNetmosIsr

        PCI串口的中断服务函数,该函数是在PCI设备的中断函数服务中调用了系统的16c550串口驱动服务函数,来完成对应的串口中断处理事务。

  • 函数pciSioNetmosGetReg

        该函数被系统串口驱动回调,用于读取PCI设备对应通道相关寄存器地址的值。

  • 函数pciSioNetmosSetReg

        该函数被系统串口驱动回调,用于设置PCI设备对应通道相关寄存器地址的值。

    pciSioNetmos.c示例中的PCI设备驱动的函数结构如图 44所示:

SylixOS_x86_PCI串口驱动浅析

图 44  pciSioNetmos.c设备驱动大体流程

5. 总结

    PCI串口驱动本质上是PCI驱动和串口驱动的一个结合,上层通过系统的串口驱动来封装出串口所需要的操作接口,下层由PCI驱动来和PCI总线上的设备进行各种操作。


名称栏目:SylixOS_x86_PCI串口驱动浅析
文章路径:http://hbruida.cn/article/pgccps.html