brucezh
驱动老牛
驱动老牛
  • 注册日期2002-01-30
  • 最后登录2007-02-01
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1840回复:12

ds中的5933dma编程

楼主#
更多 发布于:2002-06-28 16:33
我要使用5933进行不间断的数据输出(ds编程)。思路如下:
1。在设备对象类声明一个pmdl,使之指向连续内存作为缓冲区。声明一个事件作为与应用程序同步的手段。
2。应用程序通过deviceioctl得到驱动发给的缓冲区句柄。驱动把该句柄发给应用程序后把事件设为信号态。
3。应用程序一直循环,每次得到事件后向缓冲区中写入数据,事件取消,通过deviceioctl通知驱动开始输出数据。
4。驱动初始化dma,开始传送,初始化函数Initiate(
   KDevice* pDevice,
   KDmaAdapter* pAdapter,
   PMDL Memory,
   DMA_DIRECTION Dir,
   DMAREADY_CALLBACK Callback,
   KCommonDmaBuffer* pBuffer = NULL
   PVOID pContext = NULL,
   BOOLEAN BusMasterKeepAdapter = FALSE
)中Memory参数用缓冲区指针。
5。dma的callback函数中,当BytesRemaining( )不为0时,用pXfer->GetTransferDescriptors的物理地址和长度设置5933的传送地址MRAR和传送长度MRTC,设置中断允许读完成后发生中断,开始5933读操作。当BytesRemaining( )为0时,设置同步事件。
6。isr的dpc中pXfer->Continue(UseTransferSize)。

问题是:设完中断后就马上产生中断,结果就让整个运行中止了。
大虾们帮我看一下我的dma设置有没有问题?特别是我这样使用缓冲区对不对。

如果想使用KCommonDmaBuffer对象,应该如何操作?

Initiate(……)中BusMasterKeepAdapter 的含义是什么?


以上问题得到回答都给分。

最新喜欢:

ewater168ewater...
打一枪……换个地方……再打一枪……
yjhleaf
驱动小牛
驱动小牛
  • 注册日期2001-11-04
  • 最后登录2005-11-23
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-28 21:53
 这个问题,我也不会,我先给你捧场。到时候会了,可要说说。
忽如一夜春风来,千树万树梨花开。
brucezh
驱动老牛
驱动老牛
  • 注册日期2002-01-30
  • 最后登录2007-02-01
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-07-01 09:20
这个问题,我也不会,我先给你捧场。到时候会了,可要说说。


多谢捧场
打一枪……换个地方……再打一枪……
James.Ji
驱动老牛
驱动老牛
  • 注册日期2001-09-17
  • 最后登录2006-05-16
  • 粉丝0
  • 关注0
  • 积分-9分
  • 威望-8点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-07-01 09:50
/******
如果想使用KCommonDmaBuffer对象,应该如何操作?

**********/


首先声明
KDmaAdapter m_DmaAdapter;
KCommonDmaBuffer m_DmaSendBuffer;

InitializeAdapter()
{
DEVICE_DESCRIPTION dd;

   // Set up the adapter description for the slaved device
RtlZeroMemory(&dd, sizeof(DEVICE_DESCRIPTION));

dd.Version = DEVICE_DESCRIPTION_VERSION;
dd.Master = TRUE;
dd.ScatterGather = FALSE;
dd.DemandMode = FALSE;
dd.AutoInitialize = FALSE;
dd.Dma32BitAddresses= TRUE;
dd.IgnoreCount = FALSE;
dd.BusNumber = m_Cfg.Bus();
dd.DmaChannel = 0;
dd.InterfaceType = PCIBus;
dd.DmaWidth = Width32Bits;
dd.DmaSpeed = Compatible;
dd.MaximumLength = 2^32;

// 初始化适配器对象
m_DmaAdapter.Initialize(&dd);

if ((PADAPTER_OBJECT)m_DmaAdapter == NULL)
return STATUS_UNSUCCESSFUL;
else
return STATUS_SUCCESS;
}

InitializeDmaBuffer()
{
//分配1M字节空间给DMA0发送缓冲区
m_DmaSendBuffer.Initialize(&m_DmaAdapter, 1024*1024,FALSE);
if (m_DmaSendBuffer.IsValid() != TRUE)
return STATUS_UNSUCCESSFUL;

return STATUS_SUCCESS;
}

此时m_DmaSendBuffer中存放的就是虚拟地址(不确定,查看帮助)。



车到山前必有路。 虽然有些土,却是我最有感触的一句话。
brucezh
驱动老牛
驱动老牛
  • 注册日期2002-01-30
  • 最后登录2007-02-01
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-07-01 11:02
多谢,那么,dma传送初始化函数中的参数PMDL Memory必须是write 或read中传来的mdl,不能是自己创建的对不对?
打一枪……换个地方……再打一枪……
James.Ji
驱动老牛
驱动老牛
  • 注册日期2001-09-17
  • 最后登录2006-05-16
  • 粉丝0
  • 关注0
  • 积分-9分
  • 威望-8点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-07-01 11:27
多谢,那么,dma传送初始化函数中的参数PMDL Memory必须是write 或read中传来的mdl,不能是自己创建的对不对?


MDL是操作系统创建的。应用层向驱动程序发送数据的时候,操作系统根据应用层分配的分页内存而创建的,无非是形容有几个页,每个页的地址
是多少。自己应该不能创建吧?!
车到山前必有路。 虽然有些土,却是我最有感触的一句话。
brucezh
驱动老牛
驱动老牛
  • 注册日期2002-01-30
  • 最后登录2007-02-01
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-07-01 11:39
多谢,接分
有问题再请教
打一枪……换个地方……再打一枪……
James.Ji
驱动老牛
驱动老牛
  • 注册日期2001-09-17
  • 最后登录2006-05-16
  • 粉丝0
  • 关注0
  • 积分-9分
  • 威望-8点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-07-01 11:59
多谢,接分
有问题再请教


给的分太多了。我都成第一名了,
真不好意思。
车到山前必有路。 虽然有些土,却是我最有感触的一句话。
yjhleaf
驱动小牛
驱动小牛
  • 注册日期2001-11-04
  • 最后登录2005-11-23
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-07-02 09:42
 我想问一下:
  在nt下 ,我定义了一个,kdmaadapter对象,一个*kdmatransfer对象。然后 m_Transfer=new(nonpagepool)kdmatransfer(this,&m_dmaread); 这里创造对象是成功的。
 m_Transfer.Initiate(I.mdl(),fromdevicetomemory,
linkto(ondmaready),null,false);
就是在这个地方老是出现页面访问错误:page fault(0e).就是初始化不了 m_Transfer. 这个地方的I.mdl(),他所指向的内存空间到底是在什么地方分配的(分页,非分页)?
 这到底是怎么回事?难道是页面没对齐?


忽如一夜春风来,千树万树梨花开。
yjhleaf
驱动小牛
驱动小牛
  • 注册日期2001-11-04
  • 最后登录2005-11-23
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-07-02 09:43
 仁兄,借宝地一问:
  在nt下 ,我定义了一个,kdmaadapter对象,一个*kdmatransfer对象。然后 m_Transfer=new(nonpagepool)kdmatransfer(this,&m_dmaread); 这里创造对象是成功的。
 m_Transfer.Initiate(I.mdl(),fromdevicetomemory,
linkto(ondmaready),null,false);
就是在这个地方老是出现页面访问错误:page fault(0e).就是初始化不了 m_Transfer. 这个地方的I.mdl(),他所指向的内存空间到底是在什么地方分配的(分页,非分页)?
 这到底是怎么回事?难道是页面没对齐?


忽如一夜春风来,千树万树梨花开。
brucezh
驱动老牛
驱动老牛
  • 注册日期2002-01-30
  • 最后登录2007-02-01
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-07-02 11:34
这个问题最好另起一帖问一下。
不过,我想知道你是在哪里进行初始化的。我的想法是应该在处理read IRP的函数中。此处的I就是该函数传过来的IRP。
打一枪……换个地方……再打一枪……
yjhleaf
驱动小牛
驱动小牛
  • 注册日期2001-11-04
  • 最后登录2005-11-23
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-07-03 21:41
我想问一下:
在nt下 ,我定义了一个,kdmaadapter对象,一个*kdmatransfer对象。然后 m_Transfer=new(nonpagepool)kdmatransfer(this,&m_dmaread); 这里创造对象是成功的。
m_Transfer.Initiate(I.mdl(),fromdevicetomemory,
linkto(ondmaready),null,false);
就是在这个地方老是出现页面访问错误:page fault(0e).就是初始化不了 m_Transfer. 这个地方的I.mdl(),他所指向的内存空间到底是在什么地方分配的(分页,非分页)?
这到底是怎么回事?难道是页面没对齐?

忽如一夜春风来,千树万树梨花开。
mengzi
驱动牛犊
驱动牛犊
  • 注册日期2001-08-02
  • 最后登录2004-05-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-07-10 17:05
dma传送初始化函数中的参数PMDL Memory必须是write 或read中传来的mdl,不能是自己创建的对不对?
   你说得很对,只是不一定是从write 或read中传来,凡是直接IO的方式都是可以的,DeviceIoControl也可以,而且通常是从DeviceIoControl传过来。
   nt下 ,我定义了一个,kdmaadapter对象,一个*kdmatransfer对象? 完全没必要这样定义两个,一个kdmadapter对象占用不了多少内存,直接在设备的继承类的头文件中定义一个kdmaadapter的实例即可。
  DS的DMA编程主要是用户定义的回调函数代码编写,DS是个分割传输,考虑的很周到,如果你有耐心连续对source中的Kdmaxfer.cpp看上6个小时,你就会能清它的逻辑,在回调函数编写时,它的传递参数KIrp I,你不要用,如果你想获得当前的Irp,参照Dpc_ForIsr即可
游客

返回顶部