最新日志

发表于:2008-7-21 13:21:24
标签:PCI,  数据采集,  虚拟仪器  

3

基于PCI总线的数据采集系统设计与实现


写在前面

       近些年来计算机局部总线技术发生了很大程度的变化,第三代IO3GIO)技术——PCI-E无论在访问延迟、带宽,还是在扩展性方面都向前迈进了一大步,PCI-E总线技术在硬件方面发生了翻天覆地的变化,但是在软件方面还能与PCI总线保持兼容。本站在后继将会对PCI类总线投入足够的关注,并且讨论在仪器科学方面的应用。作者曾经设计过基于PCI总线方面的数据采集系统,在此对该系统进行分析总结,算是对PCI总线技术进行分析的一个开头吧~~

 

PCI总线数据采集系统实物

       设计实现的PCI数据采集卡第一版如下图所示:

点击看大图

    这是鄙人的本科毕业设计,这也是我做的第一个独立完成的较大型设计,所以这张照片我一直珍藏着,在此,我要感谢我的导师,是他给我提供了这样的平台。在PC端,我为采集卡开发了测试软件,通过该软件可以操作PCI数据采集卡,并且能够显示数据采集的信息。下图是开发的第一版PCI数据采集信息显示界面,该界面基于VC++/MFC平台开发。在此,贴上这两张图片,留作纪念。

点击看大图

       通过测试波形可以看出,设计的数据采集卡存在很大的噪声,噪声主要来自于前向通道,第一版的前向通道设计的不是很好,特别是低噪运放的电源由电荷泵的转换器提供,带载能力极弱,大大增大了前向通道的噪声,降低了信噪比。后来在设计第二版的采集系统时,很好的设计了前向通道,所以得到了非常满意的结果。

采集系统原理

    测量信号(输入范围为:±5V)CPLD时序逻辑的控制之下通过模拟选择开关和程控放大器,并在缓冲级的配合之下输入到差分转换电路,将单端信号转换成双端差分信号,差分信号具有很高的抗共模干扰能力,降低了模数转换器的输入噪声。信号送入模数转换器之后,在CPLD的时序控制之下进行采保、量化,转换完毕的数据直接送入FIFO进行数据缓存。当缓存区的数据达到2K满时,CPLDPCI总线控制器发出中断请求信号,PCI桥路控制器将接收到的中断请求信号转换成PCI总线中断请求信号,通知PC主机以DMA的方式将FIFO中的数据读入到内存,完成一次数据采集、数据传输和存储过程。PCI总线控制器在系统上电的过程中首先读取PCI配置寄存器中的配置信息,实现PCI系统的自动配置和即插即用。

 

关键技术分析

数据采集

       数据采集的核心为ADC,在PCI数据采集系统中采用了一款14位垂直电压分辨率,具有2.2Msps采样率,5V供电的模数转换器——MAX1201,该芯片是一种流水线型的ADC,由级联的若干级电路组成。每一级电路包括1个采样/保持放大器、1个低分辨率ADCDAC以及1个求和电路。流水线性ADC在采样率和分辨率方面都处于中间水平,速度最高的ADC通常采用高速比较的电路结构,精度最高的ADC可以采用Δ-Σ的方式。

 

为了充分利用ADC的直到奈奎斯特频率的优良AC特性,模数转换器采用了差分信号输入的模式。采用差分信号输入模式可以获得两倍的信号量程、提高抗干扰性能、对输入信号的放大器预处理要求降低等优点。单端信号转换成差分信号采用了低噪声、宽频运放Max4108,转换电路参考如下:

PCI总线控制器

       设计PCI设备一个比较简单的方法就是采用现有的PCI总线控制器,如果自己采用FPGA去开发PCI控制器,那么系统的开发周期将会大大加长。我在设计的时候采用了现有的PCI总线控制器。2003年时PCI总线控制器主要有AMCC公司的5933PLX公司的PCI9052PCI9054,另外TI公司也提供了一些总线控制器。起初我选择了AMCC5933,因为5933很多人搞过,中科院光机所还有一篇论文描述AMC5933,所以当初我决定选用AMC5933,并且设计了系统原理图。可惜的是5933我没有买到,该芯片面临停产,郁闷的只好把以前的方案全部推倒。万幸的是在北京出差的师兄(研究生之后就成为师兄啦~)给我带来了PCI9054的消息,PCI9054在北京很多,通过这个消息,我立即修改方案,决定采用PCI9054作为PCI主控制器。从这一段经历可以看出,在PCI设计之初,我对PCI设计方面的资讯了解不是很全面哦~~实际上,这是一方面,另一方面2003PCI设计不像如今这样满地都是,2003PCI9054芯片需要176元,如今PCI9054价格在60~70元之间。而且那个时候网上的资料也很少,文档只有datasheet。好了,言归正传,下面介绍PCI9054的设计。

 

       PCI9054PCI总线主控制器,在PCI总线上,其地位与CPU等同,都是PCI总线的主控制器。PCI9054可以向PCI总线仲裁器发出总线申请请求,获的总线之后,PCI9054可以向总线上的其它PCI设备读写数据,利用该特性,PCI9054可以直接将采集得到的数据DMA到系统内存中,而无需经过CPU的读写操作。

 

       PCI9054是一个PCI总线桥,其将本地简单的ISA总线转换成了PCI总线,所以PCI9054也可以称之为总线桥。本地ISA总线在PCI9054中称之为local bus,该总线类似于内存总线,所以可以很容易与控制器、FPGA进行时序接口。由于通过桥的转换,设计者更多的是关心local bus的行为,屏蔽了PCI总线上的具体行为,因为,PCI9054能够将local bus的行为映射成PCI的时序行为。通过这种机制,PCI设备的设计大大简化了。

 

       PCI总线是第二代IO总线,与第一代IO总线(ISAVMEEISA)相比,最大的一个优点在于plug & play(即插即用pnp)。为了实现即插即用,PCI协议规范中引入了配置空间的概念,这也是学习、设计、研究PCI总线很重要的一个概念。配置空间的提出从思路上来看应该是顺利成章的事情,其主要目的是解答CPU提出的如下三个问题:

1、  你是谁?

2、  你需要什么资源?

3、  你有什么功能?

通过这些解答这三个问题,CPU就可以为PCI设备分配资源(中断、IO地址),并且可以加载设备驱动程序。在系统上电的时刻,PCI总线控制器会通过特殊接口(例如SPI)扫描配置芯片,如果不存在配置芯片,那么采用默认值填充配置空间,否则,会从配置芯片中读取配置数据,然后设置配置空间的各项寄存器。PCIhub会检测到PCI设备的插入行为(检测PCI设备的插入是通过PRSNT1PRSNT2两个引脚实现的,此外,这两个引脚还表示了设备需求的功耗大小),然后开始发起读PCI配置空间的过程,读完配置空间之后开始分配资源,并且加载驱动,这个过程在后继blog会有详细分析~~

 

       PCI的配置空间设计非常重要,设计过程中采用了93s66作为配置芯片,如果配置空间中的数据设置错误,那么系统将无法正确加载驱动程序。共享一个好用的配置文件:rar

 

PCB布板

       PCI总线时钟频率只有33MHz,所以频率不是很高,但是需要注意的一点是PCI时钟采用的是反射升压的原理,也就是说PCI时钟是通过终端反射来提升信号幅度,这里利用了传输线的原理。这就对PCI时钟线的长度提出了要求,必须符合规范中的2.5 英寸长度要求,否则会导致多块PCI板在同一个系统中出现无法正常工作的情况。为了达到这样的长度,时钟线的布线往往采用蛇形走线,细心的朋友可能已经看出我设计的PCB存在问题,PCI接口上没有蛇形线,PCI时钟线肯定在B面(元件面)的,为什么没有看到蛇形线呢?其实,这是第一版PCI数据采集系统设计中的一个问题,只不过问题没有表现出来罢了。

 

设备驱动程序

       在开发第一版PCI设备过程中,非常得益于PLX提供的评估驱动和PLX调试工具,否则我的本科毕设不知道是否能如期完成~~在毕设完成之后的那个暑期,我开始自己编写PCI数据采集卡的设备驱动程序,该驱动的开发基于driverstudio平台,采用C++的方法进行开发,开发过程阅读了三本Windows驱动书籍,其中对我最有效的是武安河的《WDM设备驱动程序开发》。

 

       PCI数据采集卡的驱动主要完成了IO读写、DMA中断事务的处理以及DMA的数据传输。在Driverstudio中将Window DDK进行了封装,所以编写设备驱动时直接采用封装的类库就可以了,例如使用DMA传输的方法,采用KDmaTransfer。关于Windows平台下的设备驱动编写在后继的blog中将会有相应的博文进行讨论。

 

PCI数据采集卡设计心得

       对于数据采集部分的心得我不想多说了,其与应用相关,对于不用的应用具有不同的信号特征,针对不同的信号特征,可以采用五花八门的数据采集方法。例如,并行高速采样、等效采样、高分辨率采样、浮点采样等等。这里再说两句PCI总线的设计心得:

1、  得益于PCI总线控制器,PCI设备卡的设计、实现并不是十分复杂,无论是DMA数据传输还是IO数据读写都可以相对比较容易的完成,设计的重点就在于local bus时序方面的设计(通常采用FPGA实现local bus的时序接口)。传统的PCI总线频率只有33MHz,所以对于PCB设计难度不是很大。总的而言,PCI设备卡的开发应该是一个大众化的技术。

2、  对于硬件设计人员而言,设备驱动是PCI设备开发过程中遇到的一个技术高峰。对于自学、开发设备驱动,我大概用了一年左右的时间,对于系统内核的真正理解、把握是在我工作之后。当我从事软件开发一段时间过后,回过头来看看我曾经开发的PCI设备驱动,原来是如此简单!但是对一个纯硬件人员而言,的确有难度,因为硬件人员对操作系统的机制不熟悉,导致理解设备驱动处于“空中楼阁”的状态,只知其然,但不知所以然。如果要战胜这一技术高峰,需要硬件人员在软件方面的知识积累。

3、  PCI系统开发的核心技术在于总线控制器,总线控制器一般分成两大类,一类为PCI桥;另一类为PCI设备控制器。国内搞PCI总线控制器的有,但是做成产品的好像没有。PCI总线控制器分两部分,一部分为物理层的收发器,传统的PCI总线不需要,如今的PCI-E就需要了,所以更是提高了设计难度;另一部分为PCI logic core,这一部分的设计难度相对小点,实现控制通道和数据通道。对于搞高速互联技术方面研究的人员而言,这一点是需要我们去关注和投入智慧的地方。

 

点击此处查看原文 >>

系统分类: 测试测量   |    用户分类:    |    来源: 原创

评论(0) | 阅读(206)
发表于:2008-7-21 9:44:58
标签:总线接口,PCI  

2

PCI 配置空间的访问方法

访问配置空间可以采用两种方式:一是通过BIOS调用进行访问;二是在Intel CPU平台上可以通过I/O口进行访问。I/O访问方式比较简单。在开发PCI数据采集卡时,我采用了PLX公司提供的PLXMON软件对设备卡进行了调试,该软件可以访问设备卡的配置空间。另外,我又采用C语言编写了一段程序直接对配置空间进行了访问,效果不错,核心程序代码如下(需要注意的一点是,我当时在windows98平台上测试的,所以直接通过_inpd等函数访问IO端口,windows98之后IO端口对于应用程序进行了屏蔽~~只能在内核才能对IO端口进行访问):

#include <stdio.h>

#include <conio.h>

void main()

{ 

__u32 data,address;

 

address=0x80000000 + 9 * 8 * 0x100;  //插槽号为9

_outpd(0x0cf8, address);

data=_inpd(0x0cfc);

printf(“%x”, data);

address=0x80000004 + 9 * 8 * 0x100;  //访问第二个寄存器

_outpd(0x0cf8, address);

data=_inpd(0x0cfc);

printf(“%x”, data);

}

    0XCF8~0XCFB称为配置地址空间,0XCFC~0XCFF称为配置数据空间,这是两个双字空间,配置地址空间的格式如下:

最高位是配置访问使能位,要访问配置空间,使能位必须为1。位3024为保留位,只读且为0,总线号用在一个系统中从256条总线中选择一条,对应系统引导时PCI期间列表中的BUS NO项,在PC机中,每个PCI插槽的设备号是固定的,而且互不相同。功能号用来选择多功能设备中的某一个功能,最多由8种功能供选择,单功能设备此项为0。寄存器号为配置空间寄存器的索引号。最低两位必须为0

 

点击此处查看原文 >>

系统分类: 接口电路   |    用户分类:    |    来源: 原创

评论(0) | 阅读(257)
发表于:2008-7-18 9:35:31
标签:嵌入式操作系统,模拟器  

3

模拟器资源汇总

       在学习单片机知识的时候,我最苦恼的事情就是没有一个调试环境,因为我没有开发板,所以自己想开发一个数字钟之类的东西都很困难,要跑到实验室,求老师借一个仿真器~~,所以当时,我一直在找51的仿真平台,实际上也就是51模拟器。当时找到的几个模拟器比较丑陋,功能比较弱,而且只有51的模拟,没有其他硬件的模拟,所以我用的很不爽。后来,由于从事硬件方面的东西,条件好了,模拟器也就被我淡忘了。

      
       时至今日,我与计算机体系结构和操作系统走的更近了,软件开发成为我工作中的一部分,所以又提出了很强的模拟器需求。研究体系结构离不开模拟器,设计开发操作系统也离不开模拟器。在操作系统中开发一些软件,在模拟器上测试,发现早期的一些问题,并且与硬件系统的开发进行了很好的切分,所以模拟器对于软件开发人员或者是硬件体系结构开发人员都非常重要。


    在此,我整理了一些模拟器的资源,供大家参考。没有整理进去的我会在后期补充,大家还有什么好的模拟器,也可以在本页发布。

1.         bochs,历史悠久的X86模拟器(Vmware还久),也就是原来的Plex86。可运行Windows/Linux/*BSD/DOS,最大的优点是:OpenSourceFree。开源站点:http://bochs.sourceforge.net/

2.         VMips(指令模拟器)只能支持Mips指令集,有点过时,也有点局限。开源站点:http://www.dgate.org/vmips/index.shtml

3.         SPIMspim提供了一个更好的用户界面,并且能够运行在Unix/Windows/Dos下,同样完整地实现了MIPS R3000指令集,图形界面就如同大多数的调试工具一样使用,可以直接读取和解释MIPS R3000汇编指令。http://pages.cs.wisc.edu/~larus/spim.html

4.         PearPC -PowerPC 模拟器。开源站点:http://pearpc.sourceforge.net/

5.         VirtualPCVmware目前和将来最强大的竞争对手。开源站点:http://www.microsoft.com/windowsxp/virtualpc/

6.         dongfeng,(developed by chinese)一个正在处于开发阶段的mips功能模拟器,目前发布第一版,代码和功能都比较简单,可以进行思想的学习。开源站点:http://dongfeng.sourceforge.net/

7.         simos一个非常不错的模拟器,龙芯开发团队使用过的一个mips模拟器。开源站点:http://simos.stanford.edu/

8.         mips模拟器收藏室。该站点收藏了很多mips的模拟器项目,非常不错http://www.linux-mips.org/wiki/Emulators

9.    skyeye嵌入式系统模拟器。这是一个嵌入式系统的模拟器,能够在这个系统中运行uc/os、uclinux,可以模拟ARM7TDMI, ARM720T,StrongARM, XScale, Blackfin CPU核,并且模拟了多种外围设备。这个模拟器诞生在清华大学,在此推荐一下。开源站点:http://www.skyeye.org/index.shtml


点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 原创

评论(7) | 阅读(498)
发表于:2008-7-17 9:06:02
标签:Linux机制分析,嵌入式系统  

2

Linux中软中断机制分析

什么是软中断机制?

       Linux中的软中断机制用于系统中对时间要求最严格以及最重要的中断下半部进行使用。在系统设计过程中,大家都清楚中断上下文不能处理太多的事情,需要快速的返回,否则很容易导致中断事件的丢失,所以这就产生了一个问题:中断发生之后的事务处理由谁来完成?在前后台程序中,由于只有中断上下文和一个任务上下文,所以中断上下文触发事件,设置标记位,任务上下文循环扫描标记位,执行相应的动作,也就是中断发生之后的事情由任务来完成了,只不过任务上下文采用扫描的方式,实时性不能得到保证。在Linux系统和Windows系统中,这个不断循环的任务就是本文所要讲述的软中断daemon。在Windows中处理耗时的中断事务称之为中断延迟处理,在Linux中称之为中断下半部,显然中断上半部处理清中断之类十分清闲的动作,然后在退出中断服务程序时触发中断下半部,完成具体的功能。

       Linux中,中断下半部的实现基于软中断机制。所以理清楚软中断机制的原理,那么中断下半部的实现也就非常简单了。通过上述的描述,大家也应该清楚为什么要定义软中断机制了,一句话就是为了要处理对时间要求苛刻的任务,恰好中断下半部就有这样的需求,所以其实现采用了软中断机制。

 

软中断机制实现原理

      
    软中断机制的实现原理如下图所示:
点击看大图

构成软中断机制的核心元素包括:

1、  软中断状态寄存器soft interrupt stateirq_stat

2、  软中断向量表(softirq_vec

3、  软中断守护daemon

 

软中断的工作工程模拟了实际的中断处理过程,当某一软中断时间发生后,首先需要设置对应的中断标记位,触发中断事务,然后唤醒守护线程去检测中断状态寄存器,如果通过查询发现某一软中断事务发生之后,那么通过软中断向量表调用软中断服务程序action()。这就是软中断的过程,与硬件中断唯一不同的地方是从中断标记到中断服务程序的映射过程。在CPU的硬件中断发生之后,CPU需要将硬件中断请求通过向量表映射成具体的服务程序,这个过程是硬件自动完成的,但是软中断不是,其需要守护线程去实现这一过程,这也就是软件模拟的中断,故称之为软中断。

 

       一个软中断不会去抢占另一个软中断,只有硬件中断才可以抢占软中断,所以软中断能够保证对时间的严格要求。

 

Linux中软中断实现分析

       Linux中最多可以注册32个软中断,目前系统用了6个软中断,他们为:定时器处理、SCSI处理、网络收发处理以及Tasklet机制,这里的tasklet机制就是用来实现下半部的,

 

       描述软中断的核心数据结构为中断向量表,其定义如下:

       struct softirq_action

{

              void (*action)(struct softirq_action *); /* 软中断服务程序 */

              void *data;                                         /* 服务程序输入参数 */

};

 

       软中断守护daemon是软中断机制的实现核心,其实现过程也比较简单,通过查询软中断状态irq_stat来判断事件是否发生,如果发生,那么映射到软中断向量表,调用执行注册的action函数就可以了。从这一点分析可以看出,软中断的服务程序的执行上下文为软中断daemon。在Linux中软中断daemon线程函数为do_softirq()。

 

       触发软中断事务通过raise_softirq()来实现,该函数就是在中断关闭的情况下设置软中断状态位,然后判断如果不在中断上下文,那么直接唤醒守护daemon

 

       常用的软中断函数列表如下:

1、  Open_softirq,注册一个软中断,将软中断服务程序注册到软中断向量表。

2、  Raise_softirq,设置软中断状态bitmap,触发软中断事务。

 

Tasklet机制实现分析

      
        Tasklet
为一个软中断,考虑到优先级问题,分别占用了向量表中的0号和5号软中断。Tasklet机制的实现原理如下图所示:
点击看大图

    当tasklet的软中断事件发生之后,执行tasklet-action的软中断服务程序,该服务程序会扫描一个tasklet的任务列表,执行该任务中的具体服务程序。在这里举一个例子加以说明:

       当用户读写USB设备之后,发生了硬件中断,硬件中断服务程序会构建一个tasklet_struct,在该结构中指明了完成该中断任务的具体方法函数(下半部执行函数),然后将tasklet_struct挂入tasklettasklet_struct链表中,这一步可以通过tasklet_schedule函数完成。最后硬件中断服务程序退出并且CPU开始调度软中断daemon,软中断daemon会发现tasklet发生了事件,其会执行tasklet-action,然后tasklet-action会扫描tasklet_struct链表,执行具体的USB中断服务程序下半部。这就是应用tasklet完成中断下半部实现的整个过程。

 

       Linux中的tasklet实现比较简单,其又封装了一个重要数据结构tasklet_struct,使用tasklet主要函数列表如下:

1、  tasklet_init,初始化一个tasklet_struct,当然可以采用静态初始化的方法,宏为:DECLARE_TASKLET

2、  tasklet_schedule,调度一个tasklet,将输入的tasklet_struct添加到tasklet的链表中。

 

Linux中的软中断机制就是模拟了硬件中断的过程,其设计思想完全可以在其他嵌入式OS中得以应用。


点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 原创

评论(1) | 阅读(116)
发表于:2008-7-16 9:06:41
标签:虚拟仪器  

4

微型虚拟示波器的设计与实现

    接触USB总线已经有5年左右的时间了,刚接触USB时就采用了周立功代理的芯片——PDIUSBD12,该芯片为USB设备控制器,可以实现批量12Mbps的数据传输率。采用该芯片我设计了一些数据采集系统以及信号发生系统,主要应用于虚拟测试。这里我想总结一下我以前设计实现的微型虚拟示波器,并对示波器的关键技术作一下简单总结。

实物展示

       微型虚拟示波器一共设计了三版,下图是一个稳定版本。总的来说体积还是相当小的,技术指标也还可以,能和一台普通20MHz带宽的模拟示波器相媲美。

点击看大图
    上图所示的板子为示波器的核心部分,还需要前向通道电路,实现阻抗匹配、信号衰减以及程控放大。上位机的测控软件基于Labview平台,软件界面如下图所示,Labview通过CLF接口访问动态链接库,从而操作硬件系统。
点击看大图

    虚拟示波器的硬件部分完成信号获取,本质为一个数据采集系统。软件部分完成信号处理,定义具体仪器的功能。如果只需要显示时域波形,那么该仪器定义为示波器,如果需要定义成频谱分析仪,那么加入频谱分析的算法环节(FFT频域变换)就可以了。

 

       设计实现的微型虚拟示波器指标如下:

1、基于USB总线,无需外部电源,即插即测;

2、