阅读:2036回复:6
请教PCI9054使用deviceiocontrol( )、中断及DMA
PCI9054提供中断和DMA功能,现在希望实现读指定地址的内容和向指定地址写数据,使用deviceiocontrol( ),请问:我定义了IOCTL_WRITE和IOCTL_READ两个例程,如何实现中断和DMA呢?
我在5030上已经实现了IOCTL_WRITE和IOCTL_READ两个例程,现在改用9054,不知道中断和DMA的相关代码添写在哪里。 武安河的书上例子没有使用deviceiocontrol,同时也无法向指定地址读或者写数据。 高手请指点 |
|
最新喜欢:yjx200...
|
沙发#
发布于:2004-08-30 20:05
中断的实现是通过驱动程序中的中断服务例程来完成的的,当在驱动中设定好了中断服务例程,那么你的硬件就会得到相应的的中断矢量号,这样的话当你的设备产生的中断的时候就会调用你的中断服务例程与deviceiocontrol没有什么关系!至于DMA同样要通过服务历程使它与硬件挂钩!还要看你的硬件采用的dma方式!
如果愿意可以把驱动发到我得邮箱里,我们可以一起讨论! handsome414@21cn.com |
|
板凳#
发布于:2004-08-31 09:03
我还没有开始编写程序,主要就是搞不明白中断和DMA是单独的程序例程还是嵌入在读写例程中的,按照你的说法,我的读和写例程都可以使用原来的deviceiocontrol而不加改动了。
我先试试。 |
|
|
地板#
发布于:2004-09-02 09:19
我再次看了武安河的例子,发现他的DMA读的思路如下:
1.使用DO_DIRECT_IO; 2.使用METHOD_IN_DIRECT; 3.串行化读; 4.应用程序中使用ReadFile(); 5.主要例程:SerialRead――〉OnDmaReady――〉StartDMA 主要问题是:在SerialRead中初始化,由m_CurrentTransfer->Initiate()中的LinkTo(OnDmaReady)到了OnDmaReady,再到StartDMA,其中StartDMA有一条: //DMA Channel0 Local Address,自己设计的FIFO地址 m_IoPortRange0.outd(DMALADR0,0x8); 我觉得0x8是固定好了的读地址,而我要实现的功能是读写的地址不固定,由应用程序来发送读写地址,以上面的例程来看,我没有办法把地址传入驱动中去,不知道怎么解决。 6.如果不使用DMA,我可以用deviceiocontrol()将读写地址打包传入驱动后再解包,使用*.ind或者*.outd,就可以解决问题了,所以有没有办法使用deviceiocontrol()进行DMA传输呢? 下面是武安河的程序: void PCI9054Device::SerialRead(KIrp I) {。。。。。。 m_CurrentTransfer = new(NonPagedPool) KDmaTransfer(this, &m_Dma); 。。。。。。 //下面采用应用程序的数据缓冲区作为DMA数据区 status = m_CurrentTransfer-> Initiate( I.Mdl(), (I.MajorFunction() == IRP_MJ_READ) ? FromDeviceToMemory : FromMemoryToDevice, LinkTo(OnDmaReady) ); 。。。。。。 } VOID PCI9054Device::OnDmaReady(KDmaTransfer* pXfer, KIrp I) { 。。。。。。 PTRANSFER_DESCRIPTOR ptd; 。。。。。。 if ((ULONG) pXfer->BytesRemaining() == I.ReadSize()) StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length); } VOID PCI9054Device::StartDMA(ULONG PAddress,ULONG NBytes) { //下面几条语句设置DMA通道0寄存器,启动块传输方式,从FIFO读数据 //Channel0 interrupt to the PCI Bus interrupt,Done Interrupt Enable,FIFO m_IoPortRange0.outd(DMAMODE0,0x20C00); //DMA Channel0 PCI Address m_IoPortRange0.outd(DMAPADR0,PAddress); //DMA Channel0 Local Address,自己设计的FIFO地址 m_IoPortRange0.outd(DMALADR0,0x8); //DMA Channel0 Transfer Size(Bytes) m_IoPortRange0.outd(DMASIZ0,NBytes); //from the Local Bus to the PCI Bus m_IoPortRange0.outd(DMADPR0,0x8); //Channel0 Enable,Start m_IoPortRange0.outb(DMACSR0,0x3); } |
|
|
地下室#
发布于:2005-04-19 19:24
使用readfile 或者 writefile 促发dma 但不能再startdma 中更改 接收数据的起始地址,从应用程序只能传过来,一个nbytes 的参数,我我想使用一个if语句 if(nbytes==xx) 变化,接收数据的起始地址,但这种方法不保险 想用doiocontrol ,但不知道如何促发dma 希望多多指教 |
|
|
5楼#
发布于:2005-04-21 08:31
如果9054上挂了3个片子,每个片子都会向总线发起中断,这种情况下中断怎么处理?是不是每个中断上都会有一个中断号,这个号由谁来确定?
|
|
6楼#
发布于:2005-04-21 11:31
按我的理解
中断是由系统的中断控制器控制 的,自动产生中断id |
|
|