阅读:2187回复:7
站长、网友急救
我在使用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 起初我怀疑是我的内存使用有问题,可查看了一下代码,没有明显错误,我真不知如何是好。请各路英豪献计献策,在下不胜感激。 |
|
沙发#
发布于:2001-07-12 16:46
windriver我没用过,我直接用ddk来操作9054。你是用哪种DMA传送方式?(分散/集中,还是单块)
|
|
|
板凳#
发布于:2001-07-12 17:09
集中传输方式
|
|
地板#
发布于:2001-07-13 13:07
来点详细的信息,比如你的DMA链表建立的方式,每次传送数据的大小。。。。。。。。
|
|
|
地下室#
发布于:2001-07-16 16:19
DMA传送是这样的:
锁定一定的物理内存空间--一个page, 如果大于一个page我就循环几次发送给PCI卡,直到数据传送完,再释放内存。 发生错误时经常是我调用用windriver的WD_DMALock时出现问题。 |
|
5楼#
发布于:2001-07-16 16:25
可能是你占用这些内存的时间太长了,导致系统把这些内存替换到分页文件上,而当你再次使用这些内存的时候而在内存已经没有对应的了,
也有可能是因为你在这里导致堆栈溢出了 |
|
6楼#
发布于:2001-07-16 16:26
要不你把这段程序贴出来让大家看看
|
|
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); } |
|