swjaa
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2187回复:7

站长、网友急救

楼主#
更多 发布于:2001-07-12 15:03
我在使用windriver开发一个9054下的PCI接口的驱动程序,我直接使用P9054_DMAReadWriteBlock()来进行数据传输,调用一次一般不会出什么问题,循环十次也还行,可是在多的话比如一二百次就会出现BSOD。

softice给出的错误信息是这样的:

Break Due to KeBugCheckEx (unhandled kernel mode exception)
Error=7F (UNEXPECTED_KERNEL_MODE_TRAP) P1=8 P2=0 P3=0 P4=0

起初我怀疑是我的内存使用有问题,可查看了一下代码,没有明显错误,我真不知如何是好。请各路英豪献计献策,在下不胜感激。
leerom
驱动小牛
驱动小牛
  • 注册日期2001-06-08
  • 最后登录2010-08-31
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-07-12 16:46
windriver我没用过,我直接用ddk来操作9054。你是用哪种DMA传送方式?(分散/集中,还是单块)
leerom
swjaa
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-07-12 17:09
集中传输方式
leerom
驱动小牛
驱动小牛
  • 注册日期2001-06-08
  • 最后登录2010-08-31
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2001-07-13 13:07
来点详细的信息,比如你的DMA链表建立的方式,每次传送数据的大小。。。。。。。。
leerom
swjaa
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2001-07-16 16:19
DMA传送是这样的:
锁定一定的物理内存空间--一个page, 如果大于一个page我就循环几次发送给PCI卡,直到数据传送完,再释放内存。

发生错误时经常是我调用用windriver的WD_DMALock时出现问题。
guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2001-07-16 16:25
可能是你占用这些内存的时间太长了,导致系统把这些内存替换到分页文件上,而当你再次使用这些内存的时候而在内存已经没有对应的了,
也有可能是因为你在这里导致堆栈溢出了
guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2001-07-16 16:26
要不你把这段程序贴出来让大家看看
swjaa
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2001-07-16 17:32
你说的也许不无道理,但是我感觉不是这样的。
因为按照道理说每次WD_DMALock()时它都应当开一个新的空间供本次传输使用,然后在WD_DMAUnLock()时解除对该空间的控制。应该说在这个过程中不应该发生内存交换。

其实我感到问题不是出在对已有内存的依赖上,而是为什么在WD_DMALock()时就发生了异常现象。

程序结构是这样的,P9054都是windriver 给出的。

dev_send, dev_recv 进行数据的发送和接收,

/* Send data and clear IRQ */
int dev_send(P9054_HANDLE hPlxa, char *Buffer,int Offset,int Size)
{
int Actrual_Size;
DWORD data;

Actrual_Size=Size;
if (Offset>INTERFACE_SIZE)  return(-1);
if ((Offset+Size)>INTERFACE_SIZE)  
Actrual_Size = INTERFACE_SIZE-Offset;
while(P9054_ReadReg(hPlxa,0x68)&0x8000)//reset the local interrupt
{
P9054_WriteDWordLocal(hPlxa,0xc000,0);
P9054_WriteDWordLocal(hPlxa,0xc000,0);
P9054_WriteDWordLocal(hPlxa,0xc000,0);
P9054_WriteDWordLocal(hPlxa,0xc000,0);
}

data=P9054_ReadReg(hPlxa,0x68);
data|=0x100; //enable PCI Interrupt
P9054_WriteReg(hPlxa,0x68,data);

P9054_DMAReadWriteBlock(hPlxa,Offset,Buffer,Actrual_Size,0,2,0);
return (Actrual_Size);
}

/* Receive data */
int dev_recv(P9054_HANDLE hPlxa,char *Buffer,int Offset,int Size)
{
int Actrual_Size;
DWORD data;
if (Offset>INTERFACE_SIZE)  return(-1);
Actrual_Size=Size;
if ((Offset+Size)>INTERFACE_SIZE)  
Actrual_Size=INTERFACE_SIZE-Offset;

P9054_DMAReadWriteBlock(hPlxa,Offset,Buffer,Actrual_Size,1,2,0);

data=P9054_ReadReg(hPlxa,0x68);//Moved to dev_send
data|=0x100; //enable PCI Interrupt
P9054_WriteReg(hPlxa,0x68,data);
return (Actrual_Size);
}
游客

返回顶部