20楼#
发布于:2003-06-04 21:30
谢谢楼上大哥的指导,你说的很对。我也是你这样理解的。
IoMapTransfer函数执行的结果就已经编程8237的地址和记数寄存器了,至于它的屏蔽寄存器,我想也是在该函数执行的同时就打开了屏蔽位。但所有的资料上都说,在调用了IoMapTransfer之后,要给设备发送合适的命令,来通知设备启动DMA的 传输。但是我发送标志位来启动传输呢???能不能给点例子,我知道这对于做硬件的你来说有点难度,真的很感激了。 |
|
|
21楼#
发布于:2003-06-04 22:14
不用谢,如果我有环境的话早就自己去试了,你能把调试的结果告诉我就可以了。
关于“但所有的资料上都说,在调用了IoMapTransfer之后,要给设备发送合适的命令,来通知设备启动DMA的传输。”的事,我认为就是通过软件让设备使能DRQ5线。我给出的设计是硬件自动使能DRQ5线的,不需要软件再操作。如果想用软件使能DRQ5线需要更多的硬件设计,主要是要实现一个可写的寄存器,访问该寄存器就会使能DRQ5线。 你的开发处于何阶段,还有余地做硬件更改吗? |
|
|
22楼#
发布于:2003-06-05 08:28
你说的非常对,我们原来硬件的设计也是这样,硬件自己使能DREQ,为了要做到驱动来启动DMA,必须有可写的寄存器,但现在,我们的硬件上没有这样的寄存器,现在开发虽然处于关键阶段,但还是有很多的问题,硬件上的很多东西还要改,包括这个寄存器,我不知道怎么设置这个寄存器,包括硬件和软件,我看了软盘的8237工作原理,它的硬件设计上有个D触发器,输入端是DRQ,输入时钟是AMEN,这个是通过软盘接口电路的寄存器(地址0X3F2)来设置的,输出是DREQ,也就是设备端的原始DMA请求要经过AMEN的DMA允许信号有效后,放能真正有效。我理解,我的硬件设计上缺的就是这样的一个寄存器。你说呢,是不是这样?
我怎么来设计这样的寄存器?也就是硬件上怎么来实现,我感觉好象要认为定一个什么协议之类的东西来使能DMA的DREQ。 说了这么多,也不知道对不对,等着你的回答 |
|
|
23楼#
发布于:2003-06-05 09:59
我把原来的设计做了修改,你看看是否能理解
硬件上为: TC, DACK5, HALF : INPUT; SA[15..0], IOW, AEN, RSTDRV : INPUT; IRQn, DRQ5 : OUTPUT; IO_ADDRESS: PARAM; DRQ5_data : NODE; S : DFF; R : DFF; S.CLK = HALF(半满信号); S.D = VCC; S.CLRN = !(TC & !DACK5); DRQ5_data = S.Q; IRQn = S.Q; R.CLK = (SA[15..0] == IO_ADDRESS) & !IOW & !AEN & !RSTDRV; R.D = DRQ5_data; R.CLRN = !(TC & !DACK5); DRQ5 = R.Q; 软件上,在每次调用完IoMapTransfer后向IO_ADDRESS进行任意数值的IO写操作,即可启动DMA。 我的设计中,DMA由硬件自动清除,且是在DMA确定完成后清除;在产生中断时DMA肯定已具备发起的条件。 |
|
|
24楼#
发布于:2003-06-05 11:59
你的设计思路是采用两级D触发器来构造DREQ信号。我有些疑问:
触发器R的时钟输入CLK的构造,R.CLK = (SA[15..0] == IO_ADDRESS) & !IOW & !AEN & !RSTDRV,(SA[15..0] == IO_ADDRESS) 表示什么意思,能说的详细点吗?还有,就是IOW能用在这吗?这个信号是ISA的输出信号,是要写I/O的选通信号,用在这里是什么意思?我理解是要DREQ有效后,这个信号才有作用,现在,DREQ还没起作用,用在这里是什么道理?还请赐教! |
|
|
25楼#
发布于:2003-06-05 12:49
IOW是你的ISA卡的输入。
R.CLK的含义就是: 如果当前的IO写周期(即IOW有效)是访问你的ISA卡的DMA允许寄存器(寄存器的地址是IO_ADDRESS),且该周期不是CPU以外的设备发起的(AEN无效),且此时ISA总线处于工作态(RSTDRV无效),那么就可以设置触发器R,使得DRQ5线跟随DRQ5_data的变化。 任何ISA总线的IO写操作都会有效IOW信号,不管该操作是CPU、8237还是其他ISA总线主控发起的。所以IOW和DMA没有必然联系,加AEN信号就是要规定允许DRQ5的IO写操作是CPU发起的(即CPU执行了你的允许DRQ5的写寄存器指令)。 |
|
|
26楼#
发布于:2003-06-05 16:24
关于FIFO半满信号的处理,我有了新方案:
T1, T2 : DFF; T1.CLK = SYSCLK(ISA的系统时钟); T2.CLK = SYSCLK; T1.D = HALF; T2.D = T1.Q; S.CLK = T1.Q & !T2.Q;(该行取代原来的行) T1.CLRN = !(TC & !DACK5); T2.CLRN = !(TC & !DACK5); 这样就可以避免原来提到的“DMA的速度一定要比FIFO的填充速度块,否则DMA结束时FIFO的半满信号可能还没从有效变成无效,这会导致下一次DMA请求和中断请求不能产生。”问题,允许FIFO在某一段时间内的填充速度大于DMA的速度。 当然,DMA的数据流量一定要大于FIFO的数据流量,否则FIFO上溢是一定会发生的。不知道你对FIFO上溢是否有处理。 |
|
|
27楼#
发布于:2003-06-05 16:25
你以前做的那个8237的DMA,是不是很简单,没用到这么多的信号来使能DREQ有效?只要满足传输条件就触发DREQ,同时DREQ也就有效了。也就是你的DMA启动是完全由硬件来控制,驱动程序没有来干预启动。
那么你同事的驱动是怎么设计的?他是用的什么工具?? |
|
|
28楼#
发布于:2003-06-05 16:47
我以前做过同步串口的DMA,由于同步串口本身缓冲小,接收数据具有瞬时流量大的特点,所以才用的DMA。由于我用的是字符传送模式,且芯片本身有DMA引脚,所以没多少参考价值。
不过我自己在DOS + MASM的情况下验证过DMA。所以我可以肯定的说,DMA也是一种异步突发事件,合适在中断处理程序中处理。硬件和驱动是互相补充的,硬件做了的事软件就不用做了。 你面临的情况是怕万一出现故障,无法定位是硬件还是软件。所以,我认为你不要迷信开发工具,首先用你最熟悉的软件把DMA的功能调出来再说。 |
|
|
29楼#
发布于:2003-06-05 19:15
你说的很对,硬件能实现的功能,软件就没有必要再添乱了。你以前做的那个DMA的硬件,它的DMA触发条件完全是硬件控制,不需要软件(驱动)来控制,那我想问的是,在这样的情况下,驱动都干了什么?也就是DMA的启动,驱动没有参与!
|
|
|
30楼#
发布于:2003-06-05 21:06
可能是不需要参与,因为8237是有时钟端的,它对DRQ5的判断应该不是利用DRQ5的有效边沿,而是DRQ5的有效电平。所以由驱动启动,还是硬件启动DRQ5,以及启动是在打开屏蔽之前,还是在打开屏蔽之后,都应该没有影响。
你对DMA启动的含义怎么理解的? |
|
|
31楼#
发布于:2003-06-05 21:35
我理解,DMA的启动,就是使能DREQ,没有其他的意思.我想你的硬件已经能够完全做好这些事,软件就没有必要来干这个了,软件只是用来设置地址和记数寄存器,和相应的工作寄存器,控制寄存器,是通过调用DDK的函数,来实现的这些功能。所以,我很矛盾,既然硬件能启动DMA的传输,那怎么驱动的模型里面还要我们给设备发送命令来启动传输呢??
|
|
|
32楼#
发布于:2003-06-05 22:43
没作过的事,我不敢确定。所以,我也给了一个可写寄存器的方案给你,满足这个驱动编写的要求。
可能因为有的板卡是要软件启动DMA的,情况有很多: (1)要传输的数据需要判断是否全部有效,如果无效(如奇偶校验错),就不能启动本次DMA,而要清空缓冲区,重填数据。 (2)系统的DMA资源不够,或传输的数据量少,或CPU有充裕的时间进行数据传送,也不需要启动DMA,而采用其他方式。 因此,DMA的允许位对部分板卡是必要的。 |
|
|
33楼#
发布于:2003-06-06 08:56
我也是这么认为的,我感觉,你帮我做的这个方案,完全是为了满足驱动编写的需要。
现实是,我们硬件的DMA传输可以不需要软件来启动DMA的传输,只是FIFO的半满发请求,8237应答请求,达到数据的传输,在这样的情况下,驱动怎么去写?我想,不能因为软件的需要而把硬件做的复杂,你说是这样吧! |
|
|
34楼#
发布于:2003-06-06 10:32
我的问题也就是软件启动DMA是不是完全有必要,我认为和你说的一样,有的时候必要,有的时候不需要,但是驱动的模式里,确要软件来发命令给硬件以启动传输,是不是有些矛盾?
当时,你写驱动的同事有没有和你讨论这个问题,他当时有没有用软件来启动DMA,也就是你的硬件设计上有没有给他留一些口地址给他来设置DMA,以启动传输?? |
|
|
35楼#
发布于:2003-06-06 10:33
是这样的,不过硬件上还是留下更改余地的好,建议使用可编程逻辑器件。
谈了这么多,我想硬件上没有什么不清楚的了。如果你软件上还有问题,重开一帖吧。我还有几句话要说: (1)DMA取代了CPU的数据搬迁工作,使用DMA的驱动和直接读取FIFO的驱动的区别就在这里。驱动中去掉直接读取FIFO的操作,由启动DMA和有效数据块的操作代替,也就够了。 (2)由于数据填充的时间不可控,所以中断是不可少的。 (3)参考一下IO板卡自带DMA控制器的驱动也有帮助,都需要启动DMA控制器的。 (4)你的设计没有芯片自带DMA功能,所以硬件上有风险。要先在软件干预最小的情况下把DMA功能调出来,再去突破编程难题。故障点超过一个的话,会引发故障隔离的问题。 |
|
|
36楼#
发布于:2003-06-06 10:41
我没有给他留专门的DMA控制寄存器。
|
|
|
37楼#
发布于:2003-06-06 11:50
和你聊了这么长的时间了,你回答的很透彻,我还是有个问题:
你说,从我板卡上的映射内存利用DMA方式传输数据到我的主板内存,和用PIO方式从板卡映射内存传输数据到映射内存,哪个传的快点? 我看了一些DMA的资料,现在DMA的内存到内存的传输模式很少用了,因为直接用CPU控制的内存到内存的传输比用DMA的内存到内存的传输还要快,是不是自己板卡上的映射内存到主板内存上的DMA传输也比CPU控制的直接传输要快?? 我很矛盾:上面我说的这些来说要快,但从总线速率(ISA)来看,不可能太快。到底是怎么回事?? |
|
|
38楼#
发布于:2003-06-06 13:20
从IO到存储器的传输来讲,DMA是CPU访问的2倍,因为CPU要先从IO读到寄存器,再从寄存器读到存储器。
从存储器到存储器的传输来讲,通过ISA总线CPU能1次传输16位,而DMA只能传输8位(8237的特性决定只能进行8位传送)。 用DMA是为了把CPU从简单的数据搬移中解放出来。只有IO和存储器之间的传输可以提高速度。硬件上来看,是因为IO和存储器的访问可以并行,而两次存储器的访问只能串行。 |
|
|
39楼#
发布于:2003-06-06 13:23
不过DMA的优先级没有CPU高,只有CPU有空了才会释放总线给8237,所以才需要FIFO。
|
|
|