关于多个设备共享一个物理中断的问题。

kmmmmy   2010-4-27 09:46 楼主
  嘿嘿,以前在论坛看过paul,chao关于共享中断的一些回帖,刚才在看wifi驱动的时候也看到了,现在发个帖子探讨一下。
看了一下MSDN,一目了然,就是不知道具体如何实现的。
Installable ISRs and Device Drivers
Send Feedback
Installable interrupt service routines (ISRs) allow multiple devices to share interrupts and to share a single hardware platform interrupt request (IRQ). ISRs also extend the ability of the OS to process the device in the ISR in addition to the interrupt service thread (IST). If you want to allow interrupt sharing, you should update the ISRs for your device driver. If an installable ISR must recognize the device generating the input, you can usually use the generic installable ISR sample, GIISR.dll.

Because most devices indicate interrupt activity in a single register that is possibly masked, the sample installable ISR handler, GIISR.dll, is adequate for many devices. If necessary, you can write a custom installable ISR handler to implement complex interrupt detection.

You might choose to install an ISR to handle interrupts for the device. This is required if the interrupt is shared between two or more devices, which is a common occurrence with PCI devices. The installed ISR can be a generic routine that simply checks to see if the device is the one requesting service, or it can be a custom design. Giisr.dll is the generic installable ISR. If the IsrHandler and IsrDll values are provided in the device's registry key, then the driver should load the ISR DLL through the LoadIntChainHandler call.

After the ISR is loaded with LoadIntChainHandler, GIISR_INFO, defined in Giisr.h, is filled in and passed to the ISR through KernelLibIoControl with IOCTL_GIISR_INFO. The interrupt handler is unloaded with FreeIntChainHandler.

The following code example shows how to load the ISR DLL with LoadIntChainHandler.

  1. #include
  2. #include
  3. // InstallIsr is a flag that indicates that there is an ISR to be installed.
  4. //        IsrDll is the ISR DLL name, obtained from the registry.
  5. //        IsrHandler is the ISR function name, obtained from the registry.
  6. //        IfcType is the bus interface type, obtained from the registry.
  7. //        BusNumber is the PCI bus number, obtained from the registry.

  8. // Install ISR handler if there is one.
  9. if (InstallIsr) {
  10.     // Install ISR handler
  11.     g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq);

  12.     if (!g_IsrHandle) {
  13.         DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: Couldn't install ISR handler\r\n"));
  14.     } else {
  15.         GIISR_INFO Info;
  16.         PVOID PhysAddr;
  17.         DWORD inIoSpace = 1;    // io space
  18.         PHYSICAL_ADDRESS PortAddress = {ulIoBase, 0};

  19.         if (!TransBusAddrToStatic(PCIBus, 0, PortAddress, ulIoLen, &inIoSpace, &PhysAddr)) {
  20.             DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: Failed TransBusAddrToStatic\r\n"));
  21.             return FALSE;
  22.         }

  23.         DEBUGMSG(ZONE_PDD, (L"WAVEDEV: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d, PhysAddr = 0x%x\r\n", IsrDll, IsrHandler, Irq, PhysAddr));

  24.         // Set up ISR handler
  25.         Info.SysIntr = ulSysIntr;
  26.         Info.CheckPort = TRUE;
  27.         Info.PortIsIO = TRUE;
  28.         Info.UseMaskReg = FALSE;
  29.         Info.PortAddr = (DWORD)PhysAddr + ES1371_dSTATUS_OFF;
  30.         Info.PortSize = sizeof(DWORD);
  31.         Info.Mask = ES1371_INTSTAT_PENDING;

  32.         if (!KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) {
  33.             DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: KernelLibIoControl call failed.\r\n"));
  34.         }
  35.     }
  36. }


从这里可以看出,这个GIISR.dll 实现了这个功能。就是动态添加isr的功能,并且可以创建一个物理中断,和多个isr、ist 对应的 功能,真强啊。!呵呵。
学习了。

回复评论 (78)

  1. 在SPI wifi驱动中就有例子了。

  2. int installISR(MYINTRINFO* pMyIntrInfo)
  3. {
  4.         GIISR_INFO        Info;

  5.         // install the DMA ISR handler
  6.         pMyIntrInfo->hGIIsr = LoadIntChainHandler(
  7.                                                         TEXT("giisr.dll"),
  8.                                                         TEXT("ISRHandler"),
  9.                                                         (BYTE)pMyIntrInfo->irq);

  10.         if (!(pMyIntrInfo->hGIIsr)) {
  11.                 RETAILMSG(1, (TEXT("xxxxxxxx>Can not load giisr.dll\n")));   
  12.                 goto errFuncRet;
  13.         } else {
  14.                 RETAILMSG(1, (TEXT("*********> loading agiisr.dll ok\n")));   
  15.         }

  16.         Info.SysIntr = pMyIntrInfo->dwSysIntr;
  17.         Info.CheckPort  = TRUE;
  18.     Info.PortIsIO   = FALSE;
  19.     Info.UseMaskReg = FALSE;
  20.         Info.PortAddr   = (DWORD)pMyIntrInfo->IntrRgPhysAddr;
  21.     Info.PortSize   = sizeof(DWORD);
  22.     Info.Mask       = pMyIntrInfo->IntrMask;
  23.     Info.MaskAddr   = 0;


  24.         if (!KernelLibIoControl(pMyIntrInfo->hGIIsr, IOCTL_GIISR_INFO,
  25.                                 &Info, sizeof(Info),
  26.                                 NULL, 0, NULL))
  27.         {
  28.                 goto errFuncRet;
  29.         }

  30.         return 0;
  31. errFuncRet:
  32.         return -1;
  33. }
点赞  2010-4-27 09:47
这些好东西,版主其实应该m啊,期待lz进一步发掘
点赞  2010-4-27 09:54
引用: 引用 2 楼 amorous 的回复:
这些好东西,版主其实应该m啊,期待lz进一步发掘


是啊,以前有人提出一个物理中断能否对应多个系统中断的问题,大家几乎毫不犹豫的说:不可能!现在看来我们都是把人教坏了。呵呵。
点赞  2010-4-27 09:57
标记一下,慢慢研究。
点赞  2010-4-27 10:41
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
点赞  2010-4-27 11:17
慢慢研究!
点赞  2010-4-27 11:21
研究!
点赞  2010-4-27 11:21
洋洋啥爱好
点赞  2010-4-27 11:44
不好意思打错了
点赞  2010-4-27 11:45
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
点赞  2010-4-27 11:45
好好好好好好
点赞  2010-4-27 11:53
好东西,学习一下
点赞  2010-4-27 11:55

路过
点赞  2010-4-27 11:59

路过
点赞  2010-4-27 11:59
为可用分纯顶
点赞  2010-4-27 12:30
关于多个设备共享一个物理中断的问题。 [嵌入开发(WinCE)]
点赞  2010-4-27 12:42
标记,学习了
点赞  2010-4-27 12:45
慢慢研究
点赞  2010-4-27 12:48
嗯,好好研究。
点赞  2010-4-27 13:00
1234下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复