阅读:1213回复:0
PCI9054中断问题
由FPGA给9054提供LINT信号,如果想进入中断处理程序,是不是应该先在驱动中的startdevice例程中设置开启中断。即m_BAR1.outd(0x68,0x0f001D00);
只有这样本地中断才可能引起驱动程序进入中断处理程序啊?下面是我的代码 LINT应该持续大概多少时间呢? 谢谢各位帮忙。 NTSTATUS PhadriverDevice::OnStartDevice(KIrp I) { t << "Entering PhadriverDevice::OnStartDevice\n"; NTSTATUS status = STATUS_SUCCESS; I.Information() = 0; // The default Pnp policy has already cleared the IRP with the lower device // Initialize the physical device object. // Get the list of raw resources from the IRP PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources(); // Get the list of translated resources from the IRP PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources(); // Create an instance of KPciConfiguration so we can map Base Address // Register indicies to ordinals for memory or I/O port ranges. KPciConfiguration PciConfig(m_Lower.TopOfStack()); // For each memory mapped region, initialize the memory mapped range // using the resources provided by NT. Once initialized, each memory // range's base virtual address in system space can be obtained by calling // member Base(). Each memory range's physical address in CPU space can // obtained by calling CpuPhysicalAddress(). To access the memory mapped // range use member functions such as inb/outb, or the array element operator. status = m_MemoryRange0.Initialize( pResListTranslated, pResListRaw, PciConfig.BaseAddressIndexToOrdinal(0) ); if (!NT_SUCCESS(status)) { Invalidate(); return status; } // For each I/O port mapped region, initialize the I/O port range using // the resources provided by NT. Once initialized, use member functions such as // inb/outb, or the array element operator to access the ports range. status = m_IoPortRange0.Initialize( pResListTranslated, pResListRaw, PciConfig.BaseAddressIndexToOrdinal(1) ); if (!NT_SUCCESS(status)) { Invalidate(); return status; } status = m_IoPortRange1.Initialize( pResListTranslated, pResListRaw, PciConfig.BaseAddressIndexToOrdinal(3) ); if (!NT_SUCCESS(status)) { Invalidate(); return status; } // Initialize and connect the interrupt status = m_Irq.InitializeAndConnect( pResListTranslated, LinkTo(Isr_Irq), this ); if (!NT_SUCCESS(status)) { Invalidate(); return status; } // Setup the DPC to be used for interrupt processing m_DpcFor_Irq.Setup(LinkTo(DpcFor_Irq), this); // TODO: Add device-specific code to start your device. // The base class will handle completion m_PHAData=new(NonPagedPool)ULONG[256];//申名非分页缓冲区 t << "Entering PhasampleDevice::dingyi\n"; for(ULONG i=0;i<256;i++) { m_PHAData=0;//初始为0 } j=0; m_StartFlag=false;//一开始start信号是没有开始的。 //驱动加载的时候先关中断。 m_IoPortRange0.outd(INTCSR,0x0f000000); return status; } NTSTATUS PhadriverDevice::PHADRIVER_IOCTL_start_Handler(KIrp I) { NTSTATUS status = STATUS_SUCCESS; t << "Entering PhadriverDevice::PHADRIVER_IOCTL_start_Handler, " << I << EOL; // TODO: Verify that the input parameters are correct // If not, return STATUS_INVALID_PARAMETER // TODO: Handle the the PHADRIVER_IOCTL_start request, or // defer the processing of the IRP (i.e. by queuing) and set // status to STATUS_PENDING. // TODO: Assuming that the request was handled here. Set I.Information // to indicate how much data to copy back to the user. m_StartFlag=true; m_IoPortRange0.outd(INTCSR,0x0f001D00);//开启中断 I.Information() = 0; return status; } NTSTATUS PhadriverDevice::PHADRIVER_IOCTL_read_Handler(KIrp I) { NTSTATUS status = STATUS_SUCCESS; t << "Entering PhadriverDevice::PHADRIVER_IOCTL_read_Handler, " << I << EOL; // TODO: Verify that the input parameters are correct // If not, return STATUS_INVALID_PARAMETER // TODO: Handle the the PHADRIVER_IOCTL_read request, or // defer the processing of the IRP (i.e. by queuing) and set // status to STATUS_PENDING. // TODO: Assuming that the request was handled here. Set I.Information // to indicate how much data to copy back to the user. memcpy(I.IoctlBuffer(),m_PHAData,256*sizeof(ULONG)); I.Information() = 256*sizeof(ULONG); return status; } BOOLEAN PhadriverDevice::Isr_Irq(void) { // TODO: Verify that the interrupt was caused by our device. // Replace "TRUE" in next line with actual test. zhongduan=m_IoPortRange0.ind(INTCSR);//读取中断寄存器的状态 if((zhongduan&0x8000)==0) { return FALSE; } else { if (m_StartFlag) //表示在开始采集的状态 { m_IoPortRange0.outd(INTCSR,0x0f000000); j++; j = j%256; ULONG temp; temp = m_IoPortRange1.ind(0); if(m_PHAData!=NULL) { m_PHAData[j] = temp; } m_IoPortRange0.outd(INTCSR,0x0f001D00); } } // Return FALSE to indicate that this device did not cause the interrupt. // TODO: Service the device. // Minimal processing may be done here in the ISR, but // most processing should be deferred to a DPC. // Generally, you should: // o stop the device from generating interrupts // o perform any additional time-critical functions // o schedule a DPC to perform the bulk of the work. // // Request deferred procedure call // The arguments to Request may be any values that you choose //if (!m_DpcFor_Irq.Request(NULL, NULL)) //{ // TODO: Request is already in the queue // You may want to set flags or perform // other actions in this case //} // Return TRUE to indicate that our device caused the interrupt return TRUE; } |
|