?? nt_com.c
字號:
/*::::::::::::::::::: Leave critical section for adapter :::::::::::::::::::*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void host_com_unlock( tAdapter adapter )
{
register pHostCom current = & host_com[adapter];
if(current->host_adapter_status != HOST_ADAPTER_OPEN)
return; /* Exit, NULL adapter */
if (current->AdapterLockCnt != 0)
{
current->AdapterLockCnt--;
LeaveCriticalSection(¤t->AdapterLock);
}
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*::::::::::: Interrupt detection thread, one per comm port ::::::::::::::::*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
static DWORD monitor_comms( DWORD adapter )
{
register pHostCom current = & host_com[adapter]; // Set ptr to current adapter
BOOL com_locked = FALSE; // not locked!
#define EV_LS_MS_TX (EV_ERR | EV_BREAK | EV_CTS | EV_DSR | EV_RING | EV_RLSD | EV_TXEMPTY)
/* Set up event mask (without RX event) */
SetCommMask( current->handle, EV_LS_MS_TX );
forever
{
if (com_locked)
{
host_com_unlock( adapter );
com_locked = FALSE;
}
wait_comm( current );
if (current->TerminateRXThread)
{
return 0; // Terminate thread
}
if (current->EvtMask & (EV_ERR | EV_BREAK))
{
if (!com_locked)
{
host_com_lock( adapter );
com_locked = TRUE;
}
raise_rls_interrupt( &host_com[adapter].uart );
}
if (current->EvtMask & (EV_CTS | EV_DSR | EV_RING | EV_RLSD))
{
if (!com_locked)
{
host_com_lock( adapter );
com_locked = TRUE;
}
raise_ms_interrupt( &host_com[adapter].uart );
}
if (current->EvtMask & (EV_RXCHAR))
{
if (!com_locked)
{
host_com_lock( adapter );
com_locked = TRUE;
}
if (check_rda_interrupt( &host_com[adapter].uart ))
{
// reset event mask (without RX event)
// to reduce overhead from this thread.
SetCommMask( current->handle, EV_LS_MS_TX );
current->rx_waiting = FALSE;
}
else
{
raise_rda_interrupt( &host_com[adapter].uart );
}
}
if (current->EvtMask & (EV_TXEMPTY))
{
if (!com_locked)
{
host_com_lock( adapter );
com_locked = TRUE;
}
clear_tbr_flag( & host_com[adapter].uart );
}
}
}
void host_com_rx_wait( tAdapter adapter )
{
register pHostCom current = & host_com[adapter]; // Set ptr to current adapter
if (!current->rx_waiting)
{
SetCommMask( current->handle, EV_LS_MS_TX | EV_RXCHAR );// reset event mask with RX event
current->rx_waiting = TRUE;
}
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:::::::::::::::::::::::: Close comms port ::::::::::::::::::::::::::::::::*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void host_com_close( tAdapter adapter )
{
register pHostCom current;
com_close( adapter );
current = & host_com[adapter];
/*:::::::::::::::::::::::::::::::::::::::: Dealing with NULL adapter ? */
if (current->host_adapter_status == HOST_ADAPTER_OPEN)
{
/*................................................. Close RX thread */
if (current->RXThreadHandle != NULL)
{
/*................................. Tell RX thread to terminate */
current->TerminateRXThread = TRUE; // Tell RX thread to terminate
/*....................... Signal RX Thread to break out of Wait */
SetCommMask(current->handle, 0 );
/*..... Wait for RX thread to close itself, max wait 30 seconds */
WaitForSingleObject(current->RXThreadHandle, 30000);
CloseHandle(current->RXThreadHandle);
current->RXThreadHandle = NULL; // Mark thread as closed
}
#if (XMIT_BUFFER)
/*................................................. Close TX thread */
if (current->TXThreadHandle != NULL)
{
/*................................. Tell TX thread to terminate */
ReleaseSemaphore( TX_queue[adapter].wait[1], 1, NULL );
/*..... Wait for RX thread to close itself, max wait 30 seconds */
WaitForSingleObject(current->TXThreadHandle, 30000);
CloseHandle(current->TXThreadHandle);
current->TXThreadHandle = NULL; // Mark thread as closed
}
#endif //(XMIT_BUFFER)
/*.............................................. Close Comms device */
CloseHandle(current->handle);
current->handle = NULL;
/*. This makes sure that the next access to the port will reopen it */
current->ReOpenCounter = 0;
current->host_adapter_status = HOST_ADAPTER_NOT_OPEN; /* Mark adapter as closed */
}
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*::::::::::::::::::::::::: Open comms port ::::::::::::::::::::::::::::::::*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
static BOOL host_com_open( tAdapter adapter )
{
COMMTIMEOUTS comout; /* Comms time out settings */
char adapter_name[] = "COM?";
register const pHostCom current = & host_com[adapter];
switch (current->host_adapter_status) {
case HOST_ADAPTER_DISABLED:
return FALSE;
case HOST_ADAPTER_OPEN:
return TRUE;
case HOST_ADAPTER_NOT_OPEN:
/*:::::::::: Attempting to open the port too soon after a failed open ? */
if (current->ReOpenCounter != 0)
return FALSE; /* Yes */
/*::::::::::::::::::::::::::: We have a vaild adapter so try to open it */
adapter_name[3] = '1'+adapter;
current->handle = CreateFile( adapter_name,
GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
/*............................................... Validate open attempt */
if (current->handle == (HANDLE) -1)
{
current->host_adapter_status = HOST_ADAPTER_DISABLED; /* Unable to open adapter */
return FALSE;
}
/*:::::::::::::::::::::::::::::::::::::::::::::::: adapter port is open */
current->host_adapter_status = HOST_ADAPTER_OPEN;
/*::::::::::::::::::::::::::::::::::::::: Set Comms port to binary mode */
if (!GetCommState( current->handle, &(current->dcb) ))
{
host_com_close( adapter ); /* turn it into a NULL adapter */
current->ReOpenCounter = REOPEN_DELAY; /* Delay next open attempt */
return FALSE;
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Setup DCB */
current->dcb.fBinary = 1; /* run in RAW mode */
current->dcb.fOutxCtsFlow = FALSE; /* Disable CTS */
current->dcb.fOutxDsrFlow = FALSE; /* Disable DSR */
current->dcb.fDtrControl = DTR_CONTROL_DISABLE;
current->dcb.fOutX = FALSE; /* Disable XON/XOFF */
current->dcb.fInX = FALSE;
current->dcb.fRtsControl = RTS_CONTROL_DISABLE;
current->dcb.XonChar = XON_CHARACTER; /* Define XON/XOFF chars */
current->dcb.XoffChar = XOFF_CHARACTER;
/* Turn off error char replacement */
current->dcb.fErrorChar = FALSE;
/*:::::::::::::::::::::::::::::::::::::::::::::::: Set Comms port state */
if (!SetCommState( current->handle, &(current->dcb) ))
{
host_com_close( adapter );
current->ReOpenCounter = REOPEN_DELAY; /* Delay next open attempt */
return FALSE;
}
/*::::::::::::::::::::::::::::::::::::::::::::: Setup comms queue sizes */
if (!SetupComm( current->handle, INPUT_QUEUE_SIZE, OUTPUT_QUEUE_SIZE) )
{
host_com_close( adapter );
current->ReOpenCounter = REOPEN_DELAY; /* Delay next open attempt */
return FALSE;
}
/*::::::::::::::::::::: Set communication port up for non-blocking read */
GetCommTimeouts( current->handle, &comout );
comout.ReadIntervalTimeout = MAXDWORD;
comout.ReadTotalTimeoutMultiplier = 0;
comout.ReadTotalTimeoutConstant = 0;
SetCommTimeouts( current->handle, &comout );
/*:::::::::::::::::::::::::::::::: reset baud rate, line & modem control */
com_reset( adapter );
#if (XMIT_BUFFER)
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TX buffer */
current -> TX_full_length = 0;
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TX queue */
TX_queue[adapter].head = NULL;
TX_queue[adapter].tail = NULL;
TX_queue[adapter].wait[0] = CreateMutex( NULL, FALSE, NULL);
TX_queue[adapter].wait[1] = CreateSemaphore( NULL, 0, NUM_TX_BUFFERS, NULL);
/*::::::::::::::::::::::::::::::::::::::::::::::: Create Comms TX thread */
if (!(current->TXThreadHandle = CreateThread( NULL,
10*1024,
(LPTHREAD_START_ROUTINE)transmit_buffers,
(LPVOID)adapter,
0L,
¤t->TXThreadID )))
{
host_com_close( adapter ); /* Unable to create TX thread */
current->ReOpenCounter = REOPEN_DELAY; /* Delay next open attempt */
return FALSE;
}
SetThreadPriority( current -> TXThreadHandle, THREAD_PRIORITY_TIME_CRITICAL );
#endif //(XMIT_BUFFER)
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: RX buffer */
current->rx_error = 0; // no errors pending
current->rx_curr = current->rx_end = current->rx_buffer;
// buffer empty
current->rx_waiting = FALSE; // not waiting for RX interrupt
/*::::::::::::::::::::::::::::::::::::::::::::::: Create Comms RX thread */
current->TerminateRXThread = FALSE;
if (!(current->RXThreadHandle = CreateThread( NULL,
10*1024,
(LPTHREAD_START_ROUTINE)monitor_comms,
(LPVOID)adapter,
0L,
¤t->RXThreadID )))
{
host_com_close( adapter ); /* Unable to create RX thread */
current->ReOpenCounter = REOPEN_DELAY; /* Delay next open attempt */
return FALSE;
}
return TRUE;
default:
return FALSE;
}
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -