我学习PCI设计的历程 |
|
第一次对PCI感兴趣也是纯属偶然。当时用51做了一个CAN总线的设备,另外借了朋友的一个CAN设备相互通讯,调试了两周也没调通,程序检查了N遍也没找到错误。好在朋友还装了一个新买的研华的PCI CAN通讯卡,把我的CAN设备一接上去,哈哈,立即OK;从此也想摆弄摆弄PCI卡。
正好当时获悉一个朋友正计划做一块PCI CAN卡,只是没有时间做,我自告奋勇愿意替他做,朋友也欣然同意。在网上狂搜索了一把,发现PCI卡有两种做法:一是利用现成的PCI控制器,如PCI905X、AMCC5933等,硬件设计很简单;二是用CPLD/FPGA自己设计PCI控制器,当然难度非常大。当时我对PCI认识还很肤浅,虽然对CPLD/FPGA熟悉,但是PCI2.2的规范看得却是一头雾水,不得其门而入,所以还是用第一种方式吧,简单快捷。虽然我们每天都能看到很多的PCI设备,但是大多都是专用的,如PCI接口的网卡、声卡等芯片,功能固定;市面上的通用PCI控制器并不多,以PLX9052、AMCC5933为主。下了这两个片子的资料,由于对PCI规范不熟悉,看得很是吃力,这样断断续续看了一个月,大致知道怎么用了。可是新问题又来了,160脚的贴片,按照PCI规范的信号要求,双面板很难做,况且我只是做一个用SJA1000实现的CAN通讯卡,很简单的8051总线接口就可以了,根本用不着什么32位的本地总线,也不需要其他乱七八糟的信号,用9052、5933这样的大片子会使整个设计显得过于蠢重,而且这两个片子控制很复杂,用作控制SJA1000简直是杀鸡用牛刀。然后我又到处搜索其他可用的PCI控制器,终于发现oxford有一款OX9162还不错,有PCI转PC打印口的功能,128脚细密贴片,体积很小,只要把其EPP并行口模式简单变换一下就可以和SJA1000接口(其实OXFORD还有一款ox840?更合适,可惜有价无货)。
决定了怎么做,做起来就快了。首先走马观花的把PCI规范中硬件设计要注意的地方看了一下,又在网上翻了许多文章做做参考,当然还要看看EPP并行口的资料,考虑一下EPP时序怎样转化成8051时序。然后就画原理图、PCB,买了OX9162,三下两下搞好了。兴奋地把卡往PC上一插(手有点抖,很害怕一开机就冒烟:)),开机,一切都很正常,系统发现新硬件,顺利安装oxford的驱动程序,都很简单啊。通过这一次做PCI卡,我受到很大鼓舞,对PCI设计一开始就消去了恐惧心里,但是我觉得用现成的PCI控制器虽然是很简单,但是通用的PCI控制器为了做到通用,芯片规模过大,软件操作复杂,针对用户的特定应用并不能完全适用,往往需要附加外部解码逻辑,给硬件和软件设计上带来很多麻烦,并且保密性很差,几乎是只要把硬件抄出来就能够仿制。因此我萌生了用CPLD/FPGA实现PCI控制器的想法。
通过大量的资料调查我发现,用CPLD/FPGA设计PCI控制器是属于高难度的设计,而且由于具有很大的商业价值,设计源码都是保密的。我苦苦搜索了很久,才终于在Lattice公司网站发现了一个PCI设计源码,verilog语言的,并且没有明确声明该设计是正确无误的,虽然如此,这大概也是网上能够找到的唯一一个免费的PCI控制器设计源码了,真的是非常非
常珍贵。要做PCI控制器,首先就得把PCI规范看得很熟。PCI2.2规范我看了几遍,感觉还是很模糊,这个规范描述性的语言文字太多,逻辑时序画的太少,而且似乎条理上让人感觉不是那麽顺当,总之,很难理解规范到底在说些什么,必须拿许多其他厂商的PCI控制器资料和规范一起核对揣摩才能慢慢琢磨出点味道来,同时仔细研究Lattice的源代码,最后大概理解了PCI控制器的设计方法。这时我想动手用CPLD去做了,手上有一块废弃的PCI接口卡,上面正好就是EPM7128的插座,就用EPM7128SLC84实现吧,假想的PCI设备功能就是把PCI转8051接口。EPM7128S是Altera的CPLD,设计工具就用MaxplusII吧(Quartus已经出来了,不过我当时还没用过)Lattice的源码太大,必须用很大的CPLD才能实现该设计,因此我根据PCI->8051的时序特点,在Lattice源码的基础上做了很大改动,一旦对PCI规范有了较深的理解,修改这个设计源码似乎并不是很困难的事情。花了两周时间改好了,我兴奋的把设计下载到EPM7128S,然后关机、插卡、开机。。。。Oh,My God!计算机开机竟然黑屏没反应,连BIOS的自检报警声都没有听到。我一下泄了气,拔卡重启,仔细检查设计,修改,再重新烧片插卡,天,还是不行。这样反反复复修改了两三天,还是不行,这时手上还有其他的事情要做,只好把PCI设计先放弃了。过了一段时间,有了几天空闲,忽然又想起了以前的PCI设计,又来了兴致。把那个设计找出来,看了两天,才又记起来了PCI规范相关内容。然后就又改。不知道大家有没有同感,当一个设计碰到困难做不下去的时候,把它放在一边冷落一阵,然后再捡起来,这时往往会有意外的收获。我的PCI卡设计就是这样,当我修改的时候,有时很惊讶当时怎么会发生这个错误那个错误。改完了,怀着难以名状的心情重新烧片插卡,咦,PC自检的时候发现我的PCI卡的VID、PID和CLASS CODE了,咳,然后就黑屏死在那里了。不过心里还是高兴的,这说明对PCI基本时序的理解是正确的了。然后又经过几次修改,终于可以进入Win2000的启动画面了,可惜进度条到一半的时候就又死机了。然后再去改设计,这下作难了,所有的时序都已经按照自己的理解正确实现了,到底那个地方出了问题了呢?看了两天真的看不出哪里错了,咬咬牙重新做仿真,并故意设置了许多特殊情况,终于发现在某个条件下时序出错了,马上改正,立即烧片插卡,开机。。。紧张的期盼中。。。。自检、按Pause,发现了设备,F8继续,启动画面出现,焦急等待中启动画面顺利通过,登录,出现桌面----哈哈,发现新硬件,系统提示安装驱动程序!!!取消驱动安装,查看系统硬件配置,哈哈,那个大黄感叹号设备就是我的呀(嘿嘿,没装驱动当然是一个大感叹号了),再用PCIVIEW工具查看,一切正常;再用Windriver读写我的PCI卡做硬件诊断,没出现异常情况。哈哈,我终于成功啦!
硬件设备设计好了,还得要驱动程序、应用程序才能操作它呀。DriverStudio现在派上了大用场,用它的向导一步一步走下去,最后生成驱动程序框架和测试台应用程序。把驱动程序简单修改一下,编译生成 .sys。再用VC++设计一个windows的应用程序,把测试台应用程序的部分代码拷贝过来灵活运用就OK了。然后在PCI卡上焊一些指示灯和输入开关,运行程序,哈,没问题。
此后也曾经设计过几次PCI卡,没有碰到很大的困难。只是有一次把驱动程序中PCI卡的memory空间地址偏移搞错了,检查了整整一个星期,Win2000让我搞了无数次黑屏,才终于找到错处:把8写成0了 :)。
这就是我学习PCI设计的历程,看来还算是比较顺利。一点感想就是:
1. PCI规范很难看懂,必须和其他PCI控制器厂商的芯片资料对照着看,一点点的提高自己的理解,最好是有一个PCI设计的源码例子仔细揣摩。当然如果你只是想用现成的PCI控制器就不需要看这么多了,只要把PCI控制器和PCI金手指硬件连线正确基本上卡的识别就不会出问题。
2. PCI硬件设备调试非常困难,这是因为如果系统无法正常启动,软件工具根本就派不上用场,而且也没有合适的调试仪器去帮助我们查看信号到底出了什么问题(即使有了逻辑分析仪,PCI总线端最少有四十多个信号,测量起来也麻烦的要死),一切只能建立在自己对PCI时序正确可靠的理解上。
3. 驱动程序设计要非常小心,因为牵涉到对系统IO和memory空间内核模式的读写,一旦设计错误,系统很容易黑屏(系统往往连显示蓝屏的能力都没有了:))。
4. 解决了1、2,PCI设计其实很简单 :)。
Oct 20,2004
用户377235 2012-9-24 20:47
用户140341 2008-3-28 15:18