zhouandraw
驱动牛犊
驱动牛犊
  • 注册日期2004-03-19
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2036回复:6

请教PCI9054使用deviceiocontrol( )、中断及DMA

楼主#
更多 发布于:2004-08-30 19:11
PCI9054提供中断和DMA功能,现在希望实现读指定地址的内容和向指定地址写数据,使用deviceiocontrol( ),请问:我定义了IOCTL_WRITE和IOCTL_READ两个例程,如何实现中断和DMA呢?

我在5030上已经实现了IOCTL_WRITE和IOCTL_READ两个例程,现在改用9054,不知道中断和DMA的相关代码添写在哪里。

武安河的书上例子没有使用deviceiocontrol,同时也无法向指定地址读或者写数据。

高手请指点

最新喜欢:

yjx2003yjx200...
扒皮周
handsome414
驱动牛犊
驱动牛犊
  • 注册日期2003-10-09
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望12点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-08-30 20:05
中断的实现是通过驱动程序中的中断服务例程来完成的的,当在驱动中设定好了中断服务例程,那么你的硬件就会得到相应的的中断矢量号,这样的话当你的设备产生的中断的时候就会调用你的中断服务例程与deviceiocontrol没有什么关系!至于DMA同样要通过服务历程使它与硬件挂钩!还要看你的硬件采用的dma方式!


如果愿意可以把驱动发到我得邮箱里,我们可以一起讨论!

handsome414@21cn.com
zhouandraw
驱动牛犊
驱动牛犊
  • 注册日期2004-03-19
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-08-31 09:03
我还没有开始编写程序,主要就是搞不明白中断和DMA是单独的程序例程还是嵌入在读写例程中的,按照你的说法,我的读和写例程都可以使用原来的deviceiocontrol而不加改动了。
我先试试。
扒皮周
zhouandraw
驱动牛犊
驱动牛犊
  • 注册日期2004-03-19
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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);
}
扒皮周
yjx2003
驱动牛犊
驱动牛犊
  • 注册日期2004-06-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分32分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-04-19 19:24


  使用readfile 或者 writefile 促发dma
  但不能再startdma 中更改 接收数据的起始地址,从应用程序只能传过来,一个nbytes 的参数,我我想使用一个if语句
if(nbytes==xx)
  变化,接收数据的起始地址,但这种方法不保险

  想用doiocontrol ,但不知道如何促发dma

  希望多多指教
请向您的朋友推荐《名人传记》电子期刊 http://list.cn99.com/cgi-bin/getlsts?listname=zhuanji
yphilips
驱动牛犊
驱动牛犊
  • 注册日期2005-03-15
  • 最后登录2005-12-06
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望3点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-04-21 08:31
如果9054上挂了3个片子,每个片子都会向总线发起中断,这种情况下中断怎么处理?是不是每个中断上都会有一个中断号,这个号由谁来确定?
yjx2003
驱动牛犊
驱动牛犊
  • 注册日期2004-06-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分32分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-04-21 11:31
按我的理解


中断是由系统的中断控制器控制
的,自动产生中断id
请向您的朋友推荐《名人传记》电子期刊 http://list.cn99.com/cgi-bin/getlsts?listname=zhuanji
游客

返回顶部