阅读:1033回复:0
如何使用deviceiocontrol促发dma
武安河的例子,发现他的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); } ____________________ 扒皮周 您好,我遇到了和您完全一样的问题 使用readfile 或者 writefile 促发dma 但不能再startdma 中更改 接收数据的起始地址,从应用程序只能传过来,一个nbytes 的参数,我我想使用一个if语句 if(nbytes==xx) 变化,接收数据的起始地址,但这种方法不保险 想用deviceiocontrol ,但不知道如何促发dma 希望多多指教 [编辑 - 4/19/05 by yjx2003] |
|
|