再看PDD层的一个线程
DWORD CPdd6410Uart::ThreadRun()
{
while ( m_hISTEvent!=NULL && !IsTerminated() )
{
if ( WaitForSingleObject( m_hISTEvent, m_dwISTTimeout) == WAIT_OBJECT_0)
{
m_HardwareLock.Lock();
while ( !IsTerminated() )
{
DWORD dwData = ( GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM) );
if (dwData)
{
DEBUGMSG(ZONE_THREAD, (TEXT(" CPdd6410Uart::ThreadRun Active INT=%x\r\n"), dwData));
DWORD interrupts=NULL;
if ((dwData & S6410UART_INT_RXD)!=0)
{
interrupts |= INTR_RX;
}
if ((dwData & S6410UART_INT_TXD)!=0)
{
interrupts |= INTR_TX;
}
if ((dwData & S6410UART_INT_ERR)!=0)
{
interrupts |= INTR_LINE | INTR_RX;
}
if ((dwData & S6410UART_INT_MODEM)!=0)
{
interrupts |=INTR_MODEM;
}
NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts );
ClearInterrupt(dwData);
}
else
{
break;
}
}
m_HardwareLock.Unlock();
InterruptDone(m_dwSysIntr);
}
else
{
DEBUGMSG(ZONE_THREAD,(TEXT(" CPdd6410Uart::ThreadRun timeout INT=%x,MASK=%d\r\n"),m_pReg6410Uart->Read_UINTP()/*m_pReg6410Uart->Read_UINTSP()*/, m_pReg6410Uart->Read_UINTM()) );
ASSERT(FALSE);
}
}
return 1;
}
这个应该是真正的等待硬件中断的线程,等待到了,通过NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts );通知MDD的处理程序SerialEventHandler
extern "C" VOID SerialEventHandler(PVOID pMddHead);
BOOL CSerialPDD::NotifyPDDInterrupt(INTERRUPT_TYPE interruptType)
{
m_InterruptLock.Lock();
// The interrupt is define as Bit event.
m_dwInterruptFlag |= (DWORD)interruptType;
m_InterruptLock.Unlock();
if (IsPowerResumed ( ))
{
if (m_lOpenCount)
{ // If application is opened.
EventCallback( EV_POWER );
}
else
{
if (GetModemStatus() & MS_RLSD_ON)
CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED, NULL);
}
}
m_InterruptLock.Lock();
SerialEventHandler(m_pMdd);
m_InterruptLock.Unlock();
return TRUE;
}
复制代码
//==================================
MDD层的SerialDispatchThread线程(这个线程被限制没被启动起来)也会调MDD的处理函数SerialEventHandler
static DWORD WINAPI
SerialDispatchThread(
PVOID pContext /* @parm [IN] Pointer to main data structure. */
)
{
PHW_INDEP_INFO pSerialHead = (PHW_INDEP_INFO)pContext;
ULONG WaitReturn;
DEBUGMSG (ZONE_THREAD, (TEXT("Entered SerialDispatchThread %X\r\n"),
pSerialHead));
// It is possible for a PDD to use this routine in its private thread, so
// don't just assume that the MDD synchronization mechanism is in place.
if ( pSerialHead->pHWObj->BindFlags & THREAD_IN_MDD ) {
DEBUGMSG(ZONE_INIT,
(TEXT("Spinning in dispatch thread %X %X\n\r"), pSerialHead, pSerialHead->pHWObj));
while ( !pSerialHead->pDispatchThread ) {
Sleep(20);
}
}
/* Wait for the event that any serial port action creates.
*/
while ( !pSerialHead->KillRxThread ) {
DEBUGMSG (ZONE_THREAD, (TEXT("Event %X, %d\r\n"),
pSerialHead->hSerialEvent,
pSerialHead->pHWObj->dwIntID ));
WaitReturn = WaitForSingleObject(pSerialHead->hSerialEvent, INFINITE);
SerialEventHandler(pSerialHead);
InterruptDone(pSerialHead->pHWObj->dwIntID);
}
DEBUGMSG (ZONE_THREAD, (TEXT("SerialDispatchThread %x exiting\r\n"),
pSerialHead));
return(0);
}
复制代码