阅读:1604回复:0
请教pci卡中断处理问题
我用windriver开发一块基于AMCC 的S5920 PCI卡的驱动程序,因为PCI中断是电平触发,驱动响应PCI中断需要在驱动内核立即给与中断应答,使中断无效,而在中断服务线程里达不到应答效果。否则可能将一次中断信号当做多次中断,可能造成死机或挂起。
下面是中断使能用户级delphi接口函数() function S1160_IntEnable (hS1160 : S1160_HANDLE; funcIntHandler : S1160_INT_HANDLER) : BOOLEAN; var dwStatus : DWORD; addrSpace : S1160_ADDR; begin if hS1160^.Int.hThread<>0 { check if interrupt is already enabled } then S1160_IntEnable := False else begin FillChar(hS1160^.Int.Trans[0], SizeOf(hS1160^.Int.Trans), 0); { One transfer command is issued to CANCEL the source of the interrupt, } { otherwise, the PC will hang when an interrupt occurs! } addrSpace := S1160_INTCSR_SPACE; if hS1160^.addrDesc[addrSpace].fIsMemory then begin hS1160^.Int.Trans[0].dwPort := hS1160^.cardReg.Card.Item[hS1160^.addrDesc[addrSpace].index].Memory.dwTransAddr; hS1160^.Int.Trans[0].cmdTrans := RM_DWORD; end else begin hS1160^.Int.Trans[0].dwPort := hS1160^.cardReg.Card.Item[hS1160^.addrDesc[addrSpace].index].IO.dwAddr; hS1160^.Int.Trans[0].cmdTrans := RP_DWORD; end; hS1160^.Int.Trans[0].dwPort := hS1160^.Int.Trans[0].dwPort + S1160_INTCSR_OFFSET; FillChar(hS1160^.Int.Trans[1], SizeOf(hS1160^.Int.Trans), 0); { One transfer command is issued to CANCEL the source of the interrupt, } { otherwise, the PC will hang when an interrupt occurs! } addrSpace := S1160_INTCSR_SPACE; if hS1160^.addrDesc[addrSpace].fIsMemory then begin hS1160^.Int.Trans[1].dwPort := hS1160^.cardReg.Card.Item[hS1160^.addrDesc[addrSpace].index].Memory.dwTransAddr; hS1160^.Int.Trans[1].cmdTrans := WM_DWORD; end else begin hS1160^.Int.Trans[1].dwPort := hS1160^.cardReg.Card.Item[hS1160^.addrDesc[addrSpace].index].IO.dwAddr; hS1160^.Int.Trans[1].cmdTrans := WP_DWORD; end; hS1160^.Int.Trans[1].dwPort := hS1160^.Int.Trans[1].dwPort + S1160_INTCSR_OFFSET; hS1160^.Int.Trans[1].ADword := $0; hS1160^.Int.Int.dwCmds := 2; hS1160^.Int.Int.Cmd := @hS1160^.Int.Trans[0]; hS1160^.Int.Int.dwOptions := hS1160^.Int.Int.dwOptions or INTERRUPT_CMD_COPY; { this calls WD_IntEnable() and creates an interrupt handler thread } hS1160^.Int.funcIntHandler := funcIntHandler; dwStatus := InterruptEnable(@hS1160^.Int.hThread, hS1160^.hWD, @hS1160^.Int.Int, S1160_IntHandler, POINTER(hS1160)); if dwStatus>0 then begin FmtStr(S1160_ErrorString, \'InterruptEnable failed with status ($%x) - %s\', [dwStatus, Stat2Str(dwStatus)]); S1160_IntEnable := False; end else S1160_IntEnable := True; end; end; 上面的函数作用是响应中断时向S5920芯片中断控制寄存器BAR0的S1160_INTCSR_OFFSET=0X38,写0使中断无效。不知是否正确。测试时好像控制字没有写进去,造成中断不停的触发。请各位大虾赐教,先谢了 |
|