PCI 原理

转载 2011年01月16日 15:43:00
PCI 原理

        八、九 月份的时候为一块PCI卡驱动程序增加了bus master DMA和中断服务功能,到现在有一段时间没弄,一些细节有些记不大起来了,赶紧把一些要点记录一下,以免日子久了都忘记了。
        硬件是一块PCI数据采集卡,50MHz,8bit的采集速率,板上使用FPGA(Cyclone II)先对数据进行压缩等处理,然后给上位机。PCI总线用的是PLX公司的PCI9054芯片。原来的驱动不支持DMA,也不支持中断,上位机程序只能不断轮询某个标志位,如果有数据再读取。这作为一块高速的数据采集卡,实在是有点说不过去(原驱动还是出自国内某一流高校之手笔,汗)。
       驱动程序这东西感觉这一点那一点,知识点比较杂,也不知道怎么理出个条理,反正就想到什么记什么了。开发环境:VC++6.0, Win XP DDK, DriverStudio 3.1.0。

1。PCI9054芯片其实就是一个“桥”,一边是PCI总线,另一边是本地总线(local bus)。9054的作用就是把PCI的地址翻译到本地总线的地址。9054有M,C,J三种模式,我的理解就是本地总线的不同,一般用的是C模式。

2。 PCI的4个空间要映射到哪个物理地址,是由宿主机器的操作系统或bios动态配置的。宿主系统怎么知道空间的大小呢?方法是系统启动时向PCI配置空间的基地址(PCI base addresss)寄存器写一个全1的32位数,然后立刻读回来,比如说读到0xFFFF0000,后16位是0,说明这个空间有64K。就是说前16位是可写的,被写入1,而后16位是不可写的,值永远是0。然后系统就分配一个基地址,把这个地址写入前16位中,于是基地址寄存器中就保存了分配到的物理基地址。反过来说,如果一个设备要求分配64K内存,那么它就应该实现一个基地址寄存器,其高16位是可读写的,后16位是只读并且为0的(其实最后4位是选项位,可能不为0)。对于中断号的分配也简单,系统把分配的中断号写入到PCI配置空间的Interrup Line寄存器中就ok了,意思就是把PCI卡的中断请求线连接(route)到了中断管理器的几号中断脚上。

3。PCI空间配置好以后,软件通过访问配置空间的基地址寄存器,可以得知空间被映射到了哪个地址。但最先怎么访问配置空间呢?对于PC架构的机器来说,是通过PCI桥来访问的。PCI桥作为PCI总线的管理芯片,可以区别访问不同的PCI插槽。PCI桥的寄存器被固定映射到IO空间的0XCF8,0XCFC,通过操作这两个寄存器,可以访问到各个总线号、设备号、功能号的寄存器了。但开发WDM驱动的时候,这些都不需要我们自己做了,一般我们只要提供Vendor ID和Devcie ID,就可以得到基地址指针了。

4。对于驱动程序,要完成一个事务一般得分成几步,在不同的函数里完成,并且同一个函数里还得根据状态完成不同事务的某个部分。所以采用状态机是个比较适合的选择。例如对于中断的响应,在Isr_irq()里主要是查明中断原因、清除中断源,然后排队一个DpcFor_Irq,尽快返回。因为Isr_irq()是中断级高的环境,运行期间其他中断会被屏蔽,从而降低系统性能。而余下的费时工作,如读数据等操作,则由DpcFor_Irq()来完成。DpcFor_Irq()中断级低,这样在DpcFor_Irq()运行期间 Isr_irq()又可以响应其他中断了。

5。DMA传输涉及的步骤比较多,大概的流程是:
        a)SerialRead()收到一个读的IRP,初始化一个KDmaTransfer对象;
        b) KDmaTransfer会调用回调函数OnDmaReady(),在OnDmaReady()里设置硬件寄存器,开始DMA;
        c)硬件DMA完成,触发中断,经Isr_Irq(),到DpcFor_Irq(),在DpcFor_Irq()里调用KDmaTransfer的Continue()函数。这是因为一个IRP请求的数据量可能一次DMA无法完成,需要分成多次。
        d)KDmaTransfer再调用一次OnDmaReady(),OnDmaReady()判断BytesRemaining,看是否需要再启动一次硬件DMA。如果不需要,则调用KDmaTransfer的Terminate(),结束这个Transfer。然后调用PnpNextIrp(),完成这个IRP。
        对于我们的卡,情况比较特殊,在应用程序发出IRP后,还必须等采集卡发出数据就绪中断后,才可以开始DMA。因此我在OnDmaReady()里并不立刻启动硬件DMA,而是在数据就绪中断的DpcFor_Irq()里,先判断是否有Read的IRP在等待处理,再启动硬件DMA。

6。PCI总线时序的简单描述:
PCI传送以burst为单位,FRAME#信号指示burst的开始和结束。FRAME#信号使能后的第一个时钟周期是命令周期,以后是数据周期。FRAME#拉高后一个周期传送结束。
PCI master在拉低FRAME#后的第一个时钟上升沿(即命令周期)在AD[31:0}给出地址,在C/BE[3:0]给出命令。命令有I/O r/w, Memory r/w, Configuration r/w等
PCI master第二个上升沿在AD[31:0}给出数据,在C/BE[3:0]给出字节使能。
PCI master拉高FRAME#后的一个上升沿给出最后一个数据和字节使能,一个frame到此结束。
IRDY#和TRDY#用于master(initiator)和slave(target)之间指示是否就绪,如果有一方未就绪,数据周期中间会插入等待周期。

相关文章推荐

pci总线原理(转)

PowerPC汇编指令集   PowerPC 体系结构之指令集(综述) pci总线原理(转)   2011-05-04 16:06:41|  分类: hardwa...

PCI转8串口原理图

  • 2011年11月21日 11:13
  • 131KB
  • 下载

PCI卡原理图

  • 2015年04月14日 21:28
  • 222KB
  • 下载

支持subtractive功能的PCI-PCI桥工作原理

主要涉及两个概念:Bridge 和subtractive译码。还未详细修改,几年前的东西了,错误在所难免。   Pci框架概括 P2P 桥1的primary接口连接在PCI 总线0上 , P2P...
  • pankul
  • pankul
  • 2013年02月21日 17:24
  • 1561

PCI总线原理

  • 2014年09月12日 00:24
  • 652KB
  • 下载

PCI 转USB原理图

  • 2009年07月13日 16:40
  • 18KB
  • 下载

Linux枚举pci显卡设备

1         获取显卡列表 显卡属于PCI设备,可以通过枚举PCI设备,然后使用一些过滤条件将显卡设备筛选出来。Linux没有Windows那样直接枚举显卡的函数,只有借用shell脚本或者读...

PCI使用原理资料以及应用资料

  • 2011年03月10日 15:15
  • 98KB
  • 下载

PCI/PCIe基础——配置空间

PCI/PCIe基础——配置空间
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PCI 原理
举报原因:
原因补充:

(最多只允许输入30个字)