按上次的动态分配方法采用KernelIoControl函数自动分配逻辑中断号绑定物理中断,结果返回调用失败的错误。应该是带入参数IOCTL_HAL_REQUEST_SYSINTR的问题,考虑这次采用的BSP和上次不同,查找BSP文件oemioctl.c中的OEMIoControl函数内,case的选择项确实没有IOCTL_HAL_REQUEST_SYSINTR项,倒是有另外一个参数IOCTL_HAL_TRANSLATE_IRQ,据说两个参数是一样的,都可以用。使用这个参数替换KernelIoControl函数终于可以调用正确了,不过接下来的中断初始化函数InterruptInitialize又调用失败,查来查去大概是动态分配的逻辑中断号过大导致的错误。一怒之下索性自己静态分配给它中断号了,反正是一样的。
静态分配不需要调用KernelIoControl函数了,先在BSPoalintr.h里添加自定义中断的逻辑中断值,如:#define SYSINTR_MYINTR (SYSINTR_FIRMWARE + 10)。之后修改cfw.c中的OEMInterruptEnable, OEMInterruptDisableOEMInterruptDone三个函数。这主要是关于对应逻辑中断号的一些操作,包括MASKPEND还有模式寄存器等的配置,在使用中断前应当设置好,就在此处初始化和结束时改回来的。所以需要添加和前面对于的case SYSINTR_MYINTR项进行中断配置。个人觉得这些函数在InterruptInitializeInterruptDone调用时运行。最后修改armint.c中的OEMInterruptHandler(),这是和物理中断号对应的配置。主要是判断物理中断有没有发生,如没有加入对于的物理中断号到case条件需要自己加入,这要查datasheet确定所使用中断的物理中断号。并对irq返回和之前设定对应逻辑中断SYSINTR_MYINTR,如:
else if (IntPendVal == INTSRC_EINT2) // EINT2<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

return(SYSINTR_MYINTR);

这样在有此物理中断发生的时候会激发SYSINTR_MYINTR的逻辑中断。重新生成nk.bin,下载运行。就可以用InterruptInitialize()WaitForSingleObject()CreateEventCreateThreadInterruptDone函数在应用程序中实现中断了。如

 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL));

 InterruptInitialize(SYSINTR_MYINTR, hEvent, NULL, 0));//若没有修改OEMInterruptEnable(),这个调用就会失败

 while ( TRUE )

 {

  WaitForSingleObject(hEvent, INFINITE);

  // do some process...

}