PCI总线配置与应用剖析_第1页
PCI总线配置与应用剖析_第2页
PCI总线配置与应用剖析_第3页
PCI总线配置与应用剖析_第4页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、这篇文章是进行VxWorks 下 PCI 驱动开发的基础, 故将其放在首位。(当然更首位的是您有一定的Vxworks使用和开发经验)主要介绍PCI 总线配置空间,如何查看和读取PCI 配置相关信息,最后有VxWorks 下相关的示例代码。关键字 : PCI 总线vxworks PCI配置空间内存映射PlxPCI9056我把个人认为比较重要的地方:用粗体和蓝色进行了标识。如果您对文章有异议,请提出宝贵意见,您的名字和意见,将出现在下面!专用术语解释 :PCI : Peripheral Component Interconnect的缩写,一种由英特尔 ( Intel )公司 1991 年推出的用于

2、定义局部总线的标准。POST : Power On Self Test 的缩写,即上电自检,接通微机的电源后,系统将执行一个自我检查的例行程序,是 BIOS 功能的一部分。1 引言在众多的实时操作系统 (RTOS) 中,美国 WindRiver 公司的嵌入式多任务 VxWorks 实时操作系统是目前世界上用户数量最大的实时操作系统已成功应用于航空航天、武器控制、舰船、通信、科学研究等领域,如在美国的火星探测器、 爱国者导弹上均使用了VxWorks 实时操作系统。 当前在我国该操作系统也占有较大的市场分额。 VxWorks 操作系统专门对 PCI 设备提供支持,包括PCI 总线驱动和一套PCI

3、支持函数。配置总线上的设备还与硬件的体系结构和BSP 支持程度相关。本文结合PCI 原理。谈谈实际使用中的经验与体会。 ( 上面的是中国的客套话 )2 PCI 总线架构2 1 典型架构在典型的 PCI 总线系统架构中处理器、高速缓存和内存子系统通过PCI 桥连接至 JJPCI 总线。桥提供一种高速通道使得处理器可以直接访问PCI 设备。还提供高带宽的通道允许PCI 直接访问主存。桥也包含了可选择的功能,比如总线仲裁和热插拔。2 2 总线号、设备号、功能号PCI 总线可以通过桥芯片级连按与CPU 总线所隔的桥数目和同一层总线的扫描顺序,从 0开始依次编号,扩展最多 N256,0 256 就是总线

4、号; 在指定的局部总线上 按硬件扫描顺序从 O 开始依次编号,扩展最多到 32 。032就是设备号;在一个多功能PCI 设备上,最多可以实现8 种功能,按设备上配置存储区的顺序从 0 开始依次编号,称其为功能号,一般的设备只有一个功能。这三个号组合起来就可确定唯一的一个 PCI 设备 。以及该设备上的某项功能。通过这三个参数就可操作PCI 设备。3 PCI 配置空间根据 PCI 规范。每个PCI 设备都要有一个PCI 配置空间, 容量最大为256 字节,称为配置寄存器。配置寄存器是PCI 设备的硬件与其初始化软件信息交接的地方,软件可以通过它对设备进行识别和监控。3 1 配置空间组织结构256

5、 字节的空间分为头标区和设备关联区两部分,如图1 所示:PCI 设备的头标区中寄存器布局和格式大致相同,其布局如图2 所示。头标区又分为两部分,头16 个字节定义都相同,余下的48 个字节根据设备的功能类别不同而布局不同。位于0Eh 的头标识类型字段规定了后 48 个字节所用布局。 目前的规范只规定了00h 和 01hN 个头标识类型: 01h 用于 PCI to PCI 桥。00h 用于其余 PCI 设备。3 2 配置空间的功能类型 O 配置空间头标区里的寄存器实现了很多功能,这里介绍常用的几类。(1)设备识别在头标区内有五个寄存器是与一个PCI 设备的识别有关的。配置软件通过访问这些寄存器

6、很容易确定在该 PCI 总线上有什么PCI 设备。这五个寄存器都是只读的。厂商标识:标识设备的制造厂商,由PCt 规范的权威组织SIG 统一分配,以保证唯一性。如Intel公司的标识码为。8086h”“FFFFh”是无效标识。设备标识:标识某一设备,由制造厂商分配。修订版本标识:标识设备具体的修订版本,由厂商选择。头标类型:表明头标区中 10h 到 3Fh 字节空间的布局类型和该设备是否是多功能设备。位 7 用来标识一个多功能设备,为 1 则该设备是多功能设备,为 oN 是单一功能设备。位 6 到 0 规定头标区中 10h 到3Fh字节的布局类型,如上所述,目前只有两类:00h和 01h 。分

7、类代码:该寄存器有三个字节段:高字节 (0Bh) 是基本分类码,租略地对功能分类:中字节子分类码。标识具体功能;低字节 (09h) 标识所用寄存器一级的编程接 1: 3。(0Ah) 是(2)设备控制位于配置空间04h 偏移地址处的命令寄存器是控制设备产生和响应PCI周期的, 是可读写寄存器。 其各位定义和作用如下( 这里仅描述软件常用的位) : I/O 空间使能位: 控制 l,O 空间访问的响应,为 1 时,允许设备响应I O 空间的访问。 为 0 时禁止。存储空间使能位:控制本设备对存储器空间访问的响应。为1 时允许为0 时禁止。(3)基地址头标区中有 6 个双字的基地址寄存器,在加电时,

8、6 个寄存器向 POST 软件反映该设备需要多少存储器空间和 I O 空间。 POST 软件就此了解到 PCI 总线上有哪些存储设备和 IO 设备。再根据它们的容量需求将其映射定位到适当的存储器地址和 I O 地址。并把起始地址写入基地址寄存器,再启动系统。基地址寄存器<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />位 0 只读。用来表示此寄存器申请的是存储器空间还是I 0 空间。为 1 则该基址寄存器用于I 0 空间映射。此时位1 是保留位,位2 31 用来

9、把从寄存器映射到系统I O 空间, POST 再把系统分配的系统IO 空间基地址写回寄存器的2 31 位。如果位 0 为 0则要映射到存储器空间。位 1 3 是只读的其中 1 2 是类型编码,表示映射要求,表 1 列出了类型编码:64 位寄存器占据两个字其后面的基地址寄存器的偏移地址要向后推一个双字,但总容量不变,保持6 个双字大小。地址映射映射过程分为两个步骤:(a) 确定空间类别和容量要求:读取各设备基址寄存器,获取需要的空间和容量。类别可通过最低位0位判断。容量判断是把寄存器中的基地址字段的若干低位从硬件上连接到地,从PCI 总线向寄存器全写一1。再读回其值。由于接了地,读回的值中,从b

10、it4( 存储器类型 )和 bit2(I O 类型 ) 到最高位返回的O 的个数反映了所需空间。(b) 分配基地址: POST 软件分配起始地址,并向各寄存器高位字段写入分配空间的基地址,把寄存器对应的存储器和 l o 映射到系统物理地址空间去。3.3 如何得到PCI 配置信息 ?1. 如果你是初次做PCI 的驱动, 建议你安装WinDriver ,使用这个工具可以方便的查看你的PCI 板卡的信息,比如: VENDOR_ID, DEVICE_ID, BAR基地址,中断号等等,可以直观上感受一下PCI 配置。2. 也可以使用Vxworks 下相关的 PCI 函数,比如:STATUS pciDev

11、iceShow(intbusNo/* bus number */)STATUS pciHeaderShow(intbusNo,intdeviceNo,intfuncNo)3 3 VxWorks对 PCI 设备的支持VxWorks 操作系统对PCI 设备提供了专门的支持库,用户可以利用该库实现对PCI 设备的控制:通过库里的配置函数,可以动态寻找指定 PCI 设备,并可以读取和修改该设备的配置空间内容。在配置空间的映射过程中这些函数非常有用,下面列举几个常用的函数,并简单描述其功能以供参考:pciFindDevice :查找指定设备,并获得其总线号,设备号,功能号pciConfigInLong:

12、以双字为单位读入指定PCI 设备配置空间的配置。sysMmuMapAdd:对指定内存大小进行映射。PcIIntConnect :挂接中断服务程序PciIntDIsconnect: 清除中断服务程序的挂接PCI 支持库中的函数较多且功能强大,详细内容可以参照开发工具Tornado 所提供的帮助手册。3 4 VxWorks中 PCI 设备的地址映射VxWorks 操作系统在加电过程中会对设备执行地址映射操作,以便程序正确访问设备。在使用全面的 MMU 管理组件时。这个过程是系统自动完成的,但如果系统只包含了基本的MMU 功能。用户就必须手动修改 BSP 来配置。先简单了解一下内存映射表。在sysL

13、ib C 中有一张表sysPhysMemDesc描述了系统物理内存的分配,如下所示:PHYS_MEM DESC sysPhysMemDesc】=地址和长度参数必须按页对齐(4kB 4MB 的倍数 )。f 低端内存。(void 。)LOCAL_MEMLOCAL ADRS ,(void 。)LOCALMEM LOCAL DRS ,0xa0000 VM STATE_MASK FOR_ALL,VM STATE_FOR_MEMOS ,显示内存等。(void 。)Oxa0000 (void 。)Oxa0000 ,Ox60000 。VM STATE MASK FOR_ALL,VM STATE FOR MEM

14、 lO ,f为操作系统保留的高端内存(void+)Oxl 00000,(void+)Oxl 00000,Ox080000 。VM STATE_MASK_FORALL ,VM STATE FOR MEM OS ,。r 为应用程序保留的高端内存。(void )Oxl 800000,(void )Oxl 80000,LOCAL MEM SIZE Oxl80000 , 在 sys Mem Top()中会改变。,VM-sTATE_MASK_FOR_ALL,VM STATE_FOR MEM OS ,用于动态映射的条目+ DUMMY MMU ENTRY DUMMY JMU ENTRY ,:上面描述了系统物理

15、内存在逻辑内存中所分配的空间,系统引导时会根据这里的描述管理内存空间。手动配置 PCI 设备的方法就是根据 PCI 基地址寄存器的值在源码中修改上表。但是通常不推荐这样做,不然将不能适应硬件环境的变化而局限了 BSP 的使用。通常使用的方法是半自动配置方法。 所谓半自动方法是相对于包含完整 MMU 的 VxWorks 所采用的自动化方法。 自动化配置方法将自动发现 PCI 设备并自动为其分配所需空间。 但是仅包含了基本 MMU 的 VxWorks 并不会自动完成上表配置,还需要其他辅助步骤帮助系统映射内存,包括为所有设备分配不冲突的内存,以及编程使系统找到指定的 PCI 设备并分配空间。4 P

16、CI设备配置应用实例4. 1自动配置方法首先根据设备类型 f 如显示设备、网络设备 )查询总线,以此获取此类设备的 PCI 总线号、设备号、功能号、厂商号和设备标识,此处假设系统中没有同类的设备。然后。根据总线号、设备号、功能号获取该设备的PCI配置空间信息,并写入MMU用于系统物理内存分配。4 2 显示设备的配置显示设备的配置,首先要包括VxWo rks系统组件。basic MMU ”基本内存控制单元。然后再将PCI显示设备的内存空间配置到MMU 里面,否则该内存空间的访问会出现异常。如果该内存空间是预先知道的,可以在 syslib c 的 sysPhysMemDesc表中静态配置: 否则需

17、要通过动态查询得到,然后再调用MMU配置函数加入MMU 表。其简要过程如下:(1) 在 PCI 总线上查找显示设备,并获取其总线号、设备号和功能号;(2) 根据这三个号来读取该设备的内存基地址和需要的内存大小(注意:内存大小是从开始位到最高位所返回的零的个数,需要用户自己计算。内存地址要去掉低位非地址含义的位。);(3) 在 sysLib c 的 sysHwlnit()函数中调用配置函数sysMmuMapAdd,该函数将基地址和内存大小配置入MMU表,整个配置工作就完成了。5. 实战代码/*Copyright (C), 2010-08-09 - 2010-08-1X,File name: Pl

18、xPCI9056.c, PCI9056Author: qcj_21Version: V1.0Date: 2010-08-05驱动程序Description :此文件为PlxPCI9056的驱动程序, 主要作用是读取PCI9056的配置信息, 将 PCI上的8路AD信息映射到内存中由于8路AD的整个内存空间需求大于1000Byte,通过Windows下的WinDriver程序查看PCI的基地址,确定BAR2 为 8 路 AD 的映射空间。特别注意:将PCI9056映射到内存空间以后,对该空间的读写操作,要用操作内存的方式,比如:*(volatile unsigned char*)(ulPortA

19、ddr+ucRegister) ;Others:/其它内容的说明History:/修改历史记录列表,每条修改记录应包括修改日期、修改者及修改内容简述1. Author: Date: Modification:2. .*/#include <vxWorks.h>#include <drv/pci/pciConfigLib.h>#include <drv/pci/pciLocalBus.h>#include <errnoLib.h>#include <intLib.h>#include <iv.h>#include <s

20、ysLib.h>#include <vmLib.h>#include "config.h"#include "PlxPCI9056.h"#defineVENDOR_ID 0x10B5/* 厂商标识,标识设备的制造厂商 */#defineDEVICE_ID 0x9056/*设备标识,由制造厂商分配 */LOCAL UINT32 g_nMemBaseAddress = 0;/*PCI BAR2 内存映射空间 */LOCAL UINT32 g_nMemSpaceLen= 0;/*PIC内存映射空间 */LOCAL UINT32 g_nIOBa

21、seAddress = 0;/*PCI IO空间 */LOCAL UINT32 g_nCAN_IRQNum= 0;/*PCI CAN 卡的中断号 */*/* Function : PlxPCI9056的初始化/*1.根据 VENDORID, DEVICEID, Index查找自己的 PCI 设备/*2.读取 PCI 配置信息/*3.对内存空间进行映射/* Input:无/* RetValue :成功返回 OK, 失败返回 ERROR/* Author: qcj_21 at 2010-8-5 14:02:19/*/STATUS PCI_CAN_Init(void)intnIndex= 0;int

22、nPciBusNO= 0;/*总线号,0 255*/intnDeviceNO= 0;/* 设备号 ,0 32*/intnFuncNO= 0;/*设备功能号 , 0 8*/UINT32 nMemBaseAddress= 0;/* 内存映射的基地址*/UINT32 nIOBaseAddress= 0;/*IO 基地址 */UINT32 nMemSpaceLen= 0;/*内存映射空间的容量即长度UINT32 nIOSpaceLen= 0;/*IO 空间容量 */UINT32 nIRQNum= 0;/* 中断号 */UINT32 nCommand= 0;STATUS nStatus= 0;*/UIN

23、T32 nTemp= 0;UINT32 nOffset = 0;/* 查找指定设备,并获得其总线号,设备号,功能号*/if( OK != pciFindDevice(VENDOR_ID, DEVICE_ID, nIndex, &nPciBusNO, &nDeviceNO, &nFuncNO) )printf("pciFindDevice() functon not find the device !");return ERROR;elseprintf("Find the PCI device !, nIndex = %d, nPciBusN

24、O = %d, nDeviceNO = %d, nFuncNO = %d n", nIndex, nPciBusNO, nDeviceNO, nFuncNO);pciConfigInLong(nPciBusNO, nDeviceNO, nFuncNO, PCI_CFG_COMMAND, &nCommand); pciConfigOutLong(nPciBusNO, nDeviceNO, nFuncNO, PCI_CFG_COMMAND, nCommand | CSR_MEM_EN | CSR_BM_EN );nStatus = pciConfigInLong(nPciBusN

25、O, nDeviceNO, nFuncNO, PCI_CFG_BASE_ADDRESS_2, &nMemBaseAddress); /* 得到内存映射基地址 */if(OK != nStatus) printf("Cannot find memory base address register n");nStatus = pciConfigInLong(nPciBusNO, nDeviceNO, nFuncNO, PCI_CFG_BASE_ADDRESS_1, &nIOBaseAddress); /* 得到 IO 映射基地址 */if(OK != nStat

26、us) printf("Cannot find IO base address register n");nStatus = pciConfigInByte(nPciBusNO, nDeviceNO, nFuncNO,PCI_CFG_DEV_INT_LINE,&nIRQNum);/* 得到中断号 */if(OK != nStatus) printf("Cannot find Interupt Register. n");g_nCAN_IRQNum = nIRQNum;printf("nMemBaseAddress=%x, nIOBase

27、Address=%x, nIRQNum=%d n", nMemBaseAddress, nIOBaseAddress, nIRQNum);if(0 = (nMemBaseAddress&PCI_BAR_SPACE_MEM)/bit0 = 0,表示内存映射/* 首先需要判断所需内存的大小 ,根据 PCI 的规范,将内容全 1 ,写回就可以得到大小 */ pciConfigOutLong(nPciBusNO, nDeviceNO, nFuncNO, PCI_CFG_BASE_ADDRESS_2, 0xFFFFFFFF); pciConfigInLong (nPciBusNO, nDeviceNO, nFuncNO, PCI_CFG_BASE_ADDRESS_2, &nMemSpaceLen);nMemSpaceLen = nMemSpaceLen;/* 取反*/*nMemSpaceLen += 1;/将上一步的值加上1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论