1、Overview

在最新发布的BSP中,风河公司基本上都提供了对PCI BUS的支持,本文主要探讨PCI BUS在VxWorks系统中的实现。

2、PCI Address Space and Memory Mapping

PCI BUS有三种地址空间:IO Space、Memory Space and Configuration Space。每个PCI设备都通过Configuration Space中的Base Address Registers(BAR)映射到内存或者IO空间,这样就不用像ISA BUS那样,通过硬件Jumpers来设置板卡的Address。PCI BUS的所有配置基本上都是通过Configuration Space的寄存器来控制的。但是,每个PCI Device都必须先配置才能使用,这意味着PCI Device的基地址和中断都必须被系统分配到资源,并且PCI Device能够对正常的PCI配置操作做出回应。

WRS提供一个名为pciConfigLib.c的标准库给用户访问PCI配置空间,该标准库使用PCI规范中定义的访问机制1和机制2来支持Host-Bridge,风河本身提供的第三个访问机制,名为机制0是针对非标准PCI Bridge的,机制0主要是靠调用BSP包中的特定routine来实现PCI配置空间的read/write的,与此同时,这些特定的routine接口和前面的介绍的机制1和机制2是相同的。pciConfigLib.c提供访问PCI配置空间内任何寄存器的routine,该库同样提供一些用于扫描PCI BUS寻找特定PCI 设备实例的方法,另外该库也提供一些简单的配置接口用于配置简单的PCI设备。

3、PCI Interrupt Handling

PCI 规范并没有详细说明PCI中断信号是如何路由到中断控制器的。每个PCI设备都有4个可用的中断PIN,分别命名为A,B,C和D。每个单功能的PCI设备都被要求使用中断PIN A来产生中断,而对于多功能PCI设备,每个功能使用一个中断PIN,但是根据PCI规范,每个PCI设备最多可提供8个功能,这样就必须两个功能共用一个中断PIN。当产生PCI中断时,PCI中断处理系统需要调用多个中断服务程序,那么最简单的方法就是每个ISR都调用一遍,ISR必须有能力判断该次中断源是否是自己产生的,如果不是,则立即返回,并接着会调用下一个中断服务程序。

pciIntLib.c提供一些routine来挂接多个ISR到一个中断LINE上,该库通过挂接一个特殊的ISR,该ISR会遍历一个中断链表,所有共用同一个中断的ISRs都被放在这个链表中。pciIntConnect()用于将设备的ISR挂接到中断链表上,而pciIntDisConnect()用于删除中断链表上的一个ISR。

例子:

pciInitConnect(Vector, ISR1, PARAM1);
pciInitConnect(Vector, ISR2, PARAM2);
pciInitConnect(Vector, ISR3, PARAM3);

上面3个语句把ISR1,ISR2,和ISR3分别挂接到中断向量为Vector的链表intList里面,那么当中断发生时,会执行下面一个函数:

void sISR(void)
{
       while(intList->next !=NULL)
        {
                (*intList->INT_ISR)(PARAM);/*分别调用ISR1,ISR2,ISR3,没写很具体,只是个大概理解*/
        }
}

4、VxWorks中的PCI 配置策略

在BSP中,必须定义洪INCLUDE_PCI来支持PCI BUS,宏PCI_CFG_TYPE必须定义为一下几种类型:

VxWorks下的vxbus驱动程序最重要的部分就是驱动程序源代码文件,源文件描述了设备如何和VxBus、VxWorks OS交互。但是,VxWorks 设备驱动程序还需要另外一些文件,这些附加文件能够帮助你将自己编写的驱动集成到VxWorks编译环境中去,这也是发布驱动程序最重要的一步。本节主要讨论如何在源码树中找到相关的驱动程序文件和其他附加文件。最后还说明驱动程序的各个部分是如何安装在VxWorks OS中的。

文件位置

在开发驱动程序之前,了解驱动程序文件在VxWorks源码树中的位置是非常重要的,驱动程序文件主要分布在源码树中的3个不同位置。

  • installDir/vxworks-6.x/target/3rdparty 第三方提供的基于VxBus驱动模型的驱动,它们一般都做为插件安装到现有的VxWorks开发环境中
  • installDir/vxworks-6.x/target/src/hwif 风河官方提供的基于VxBus驱动模型的驱动程序,它们一般都作为标准产品的一部分,或者作为补丁来升级。
  • installDir/vxworks-6.x/target/src/drv 风河官方提供的基于传统模型的驱动程序,和VxBus不兼容
风河官方的驱动程序

根据驱动程序的类型,installDir/vxworks-6.x/target/src/hwif目录下的驱动被组织成不同的子目录,例如,定时器的驱动程序在目录installDir/vxworks-6.x/target/src/hwif/timer

第三方的驱动程序

第三方驱动程序的组织方式允许驱动程序开发厂商和开发者创建第三方驱动程序,不需要担心不同厂商的文件之间的命名空间冲突。每一个想提供VxWorks驱动程序的厂商必须在3rdparty目录创建自己的子目录,比如说,Acme公司计划为vxworks开发第三方设备驱动程序,那么就必须在3rdparty目录创建自己的目录installDir/vxworks-6.x/target/3rdparty/acme,在这个目录下,不同类型的驱动程序又组织成不同目录,跟hwif目录一样。

驱动程序文件例子:wrsample

风河公司提供的VxBus的驱动程序例子位于目录:installDir/vxworks-6.x/target/3rdparty/windriver/wrsample,这些文件可以被当做模板来帮助你开发第三方驱动程序,具体信息请参考wrsample目录下的README文件。

其他必须的文件

尽管一个驱动程序可以包括很多文件,比如多个源文件和多个头文件,但是一个标准的VxWorks驱动程序有一个最小的文件集,对于大多数vxworks驱动程序最少要求6个文件:

  • 驱动程序源文件 实现驱动程序控制逻辑
  • 组件描述文件(CDF) 主要用于将驱动程序集成到VxWorks编译环境中,以便于配置
  • 一个driverName.dc文件 提供驱动注册例程的原型
  • 一个driverName.dr文件 提供一小段调用驱动注册例程的代码
  • README文件 提供版本信息
  • Makefile文件 提供编译规则

一般情况下,CDF文件,dc文件,dr文件都被认为是驱动程序的配置文件,下面详细介绍这些文件。

驱动程序源文件

驱动程序源文件包含了驱动程序功能的实现逻辑,它们被放在目录installDir/vxworks-6.x/target/src/hwif, 第三方的被放在目录installDir/vxworks-6.x/target/3rdparty。很多VxWorks设备驱动程序只包含一个源文件,一个驱动程序可以包含一个或者几个可选的头文件;但是驱动程序可以包含多个源文件,但是此时必须在Makefile里面提供各个模块的依赖规则。下面以文件vxbCn3xxxTimer.c来说明VxWorks驱动程序的结构。

设备驱动程序的第一部分是一个描述VxBus初始化阶段要调用的例程的结构:

本文根据VxWorks系统启动的流程,分文件来梳理了启动过程中执行的函数,对了解VxWorks的启动流程有比较大的帮助。

一、romInit.s -> romInit()

/* romInit - entry point for VxWorks in ROM */

1. initialize CPU and memory

2. copy bootrom to ROM_TEXT_ADRS

3. initialize STACK

4. lock INTERRUPT

5. jump to romStart()

二、romStart.c->romStart()

/* this is the first C code after reset */

1. clear memory

2. copy vxWorks ROM image to RAM

3. uncompress if necessary

4. jump to the object code ENTRY after uncompress

  • usrEntry - entry point for vxWorks_romCompress, vxWorks_rom and bootrom
  • sysInit() for vxWorks in RAM(Uncompress)

三、sysALib.s->sysInit()

1、Introduction

本章讨论和基于VxBus驱动程序模型的VxWorks设备驱动程序的相关核心概念,并特别剖析了VxBus设备驱动程序框架,主要包括以下信息:

  • 设备驱动程序相关的文件和目录结构
  • VxBus方法
  • VxBus设备驱动程序的生命周期

除此之外,本章还包括了在SMP环境下开发设备驱动程序的guidline。本章解释的一些概念通常适用于所有的Device-Specific Driver。

2、驱动程序类别

关于设备和管理设备的驱动程序最基本的信息就是:这个设备有哪些功能。不同设备可以执行不同的任务,有用于读写磁盘或者其他不易失数据存储器的设备,有用于打印文本或者图形到视频显示器的设备,也有其他用于控制机器人手臂等用途的设备。

对于每一种功能,可能会有多种设备能够实现这一的功能,比如在显示器上显示信息这个功能,显示控制器可以是VGA,也可以是PCIe总线上的有几MRAM buffers的现代显示控制器。但是,不管是哪一种设备,其潜在的目的都是一样的。但是由于功能的相似性,设备驱动程序可以根据设备执行的任务来分为几类,以下是风河公司定义的几种设备驱动程序类别。

2.1 串行设备驱动程序

串行设备驱动程序管理面向终端和使用串行接口(RS232,RS422)的设备,这些设备都被连接到VxWorks的IO系统,并可以在控制台中进行配置,软件可以使用open,read,write,ioctl,close等标准接口来访问这些设备,在VxBus的框架下,串行设备驱动程序的安装目录在:

installDir/vxworks-6.x/target/src/hwif/sio

2.2 存储设备驱动程序

存储设备驱动程序当然是管理那些面向磁盘、磁带、移动闪存和在板闪存的接口,这些设备的一些通用特性有:

VxBus是风河公司新的设备驱动程序架构,是VxWorks新增的特性,它是在VxWorks6.2及以后版本被增加到VxWorks中的。本文结合基于PCI2040数据采集卡驱动的开发过程,分析了VxBus架构下驱动的设计实现。

VxBus简介

VxBus是指在VxWorks中用于支持设备驱动的特有的架构,这种架构包含对minimal BSP的支持。它包括以下功能:

  • 允许设备驱动匹配对应设备;
  • 提供驱动程序访问硬件的机制;
  • 软件其他部分访问设备功能;
  • 在VxWorks系统中,实现设备驱动的模块化。

VxBus在总线控制器驱动程序服务的支持下,能在总线上发现设备,并执行一些初始化工作,使驱动与硬件设备之间正常的通讯。

VxWorks VxBus Demonstration

图1是VxBus 在整个系统中的位置示意图。从图1中可以看到,VxBus起到了辅助总线的作用,提供了对总线控制驱动的支持。

在VxWorks6.2版本发布前,设备驱动并不能被集成到VxWorks工程配置当中,为了添加或移出设备驱动,需要有丰富的BSP和驱动开发相关的知识。作为VxWorks系统组件的一部分,VxBus消除了上面遇到的一些难题,各种驱动和支持组件的添加与删除完全可以在Workbench工程中进行,不需要BSP和驱动相关的知识,也不会在添加或者删除驱动时增加管理VxWorks工程的额外工作。

vxBus下对设备管理做了更为详细的划分,简单说来,硬件称为device,软件叫做driver。如果一个device出现在硬件列表中,启动时需要到driver的队列中去找相应的driver,如果找到,二者结合成一个instance,否则在vxBusShow里可以看到一个orphan。使用vxBusShow可以比较清晰的看到driver列表和device列表以及orphan列表。

如果需要增加一个设备,首先要修改的是hcfDeviceList,这是hwconf.c中的一个数组,这个数组中列有本系统中所有需要初始化的硬件设备。例如: