引用自:http://blog.csdn.net/shuiii/archive/2007/12/01/1910321.aspx
理应用程序或驱动程序的中断需要两个步骤。首先,中断必须使用关联的事件进行初始化。其次,IST 必须等待响应内核中断的中断事件。
中断初始化
以下示例代码将设置 IST 并将 IST 与特定的中断相关联。初始化中断的关键步骤包括:
创建事件
获取 IRO 的系统中断号
创建挂起的中断服务线程 (IST)
调用 InterruptInitialize 以创建 IRQ 与事件的关联
创建未挂起的 IST 可能会导致 InterruptInitialize 失败,因为该事件已经处于等待状态。
将线程优先级设置为相应的优先级
恢复 IST
Void SetupInterrupt( void )
{ // 创建事件
//
g_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hevInterrupt == NULL)
{ RETAILMSG(1, (TEXT("DEMO: Event creation failed!!!\r\n")));
return;
}
// 使 OAL 将 IRQ 转换成系统 IRQ
//
fRetVal = KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ,
&dwIrq,
sizeof( dwIrq ),
&g_dwSysInt,
sizeof( g_dwSysInt ),
NULL );
// 创建等待信号的线程
//
g_fRun = TRUE;
g_htIST = CreateThread(NULL, // 安全性
0, // 没有堆大小
ThreadIST, // 中断线程
NULL, // 没有参数
CREATE_SUSPENDED, // 创建挂起的线程
&dwThreadID // 线程 ID
);
// 设置线程的优先级 - 随意选择了 5
//
m_nISTPriority = 5;
if( !CeSetThreadPriority( g_htIST, m_nISTPriority ))
{ RETAILMSG(1,(TEXT("DEMO: Failed setting Thread Priority.\r\n")));
return;
}
// 初始化中断
//
if ( !InterruptInitialize(g_dwSysInt,g_hevInterrupt,NULL,0) )
{ RETAILMSG (1, (TEXT("DEMO: InterruptInitialize failed!!!\r\n")));
return;
}
// 使线程启动
//
ResumeThread( g_htIST );
}
需要特别注意的是,调用 InterruptInitialize 仅获取 SYSINTR 值和事件。内核不知道或者说也不关心将要等待事件的线程。这样一来,就可以建立多种应用程序和驱动程序体系结构。应用程序的简单主循环可以初始化中断,然后立即等待事件。一个中断只能与一个事件关联,并且调用 WaitForMultipleObjects 的过程中不能使用该事件。我们将会看到一个简单的线程为中断服务。这是大多数实现方案中的标准解决方法。
应用程序中断服务例程:
以下是中断服务线程 (IST) 的示例代码。此 IST 中断处理线程的关键组件包括:
等待中断事件
确认有一个来自操作系统的事件
在尽可能短的时间内处理中断
调用 InterruptDone()
在调用 InterruptDone 之前,操作系统不会提供有关此 IRQ 的另一个中断。
再次等待中断事件
DWORD WINAPI ThreadIST( LPVOID lpvParam )
{ DWORD dwStatus;
// 始终检查运行标志
//
while( g_fRun )
{
dwStatus = WaitForSingleObject(g_hevInterrupt, INFINITE);
// 确保拥有对象
//
if( dwStatus == WAIT_OBJECT_0 )
{
// 在此处理中断
//
g_dwInterruptCount ++;
// 完成中断
//
InterruptDone( g_dwSysInt );
}
}
return 0;
}[