📄 serialcom.c
字号:
default:
{
/* error occured */
errorHandler(__LINE__, __FILE__, "Default called");
break;
}
}
} while (startRead && (event != CLOSE_DOWN_EVENT));
if (event == CLOSE_DOWN_EVENT)
{
break;
}
}
} /* end while */
CloseHandle(osRead.hEvent);
SetEvent(rxDownEvent);
ExitThread(0);
}
void clearBuffer(void)
{
/* flush the port for any operations waiting and any data */
PurgeComm(comHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
/* the internal queue pointers */
txSize = 0;
rxSize = 0;
rxIn = 0;
rxOut = 0;
txIn = 0;
txOut = 0;
}
static bool_t init(void)
{
char configurationString[128];
clearBuffer();
/* mutex for sync of write and read */
InitializeCriticalSection(&rxMutex);
InitializeCriticalSection(&txMutex);
/* event for internal communication */
newTxDataEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
txCloseDownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
txDownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
rxCloseDownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
rxDownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
dataReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (newTxDataEvent == NULL || txCloseDownEvent == NULL || rxCloseDownEvent == NULL || txDownEvent == NULL || rxDownEvent == NULL || dataReadEvent == NULL)
{
errorHandler(__LINE__, __FILE__,"Create event failure in init");
return FALSE;
}
/* create the file handle */
comHandle = CreateFile(comPortString, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if (comHandle == INVALID_HANDLE_VALUE)
{
errorHandler(__LINE__, __FILE__, "Create file handle failed");
return FALSE;
}
//sprintf(configurationString, "baud=%lu parity=E data=8 stop=1", baudRate);
sprintf(configurationString, "baud=%lu parity=N data=8 stop=1", baudRate);
if (!setComDefault(configurationString))
{
return FALSE;
}
return TRUE;
}
/*----------------------------------------------------------------------------*
* NAME
* UartDrv_Configure
*
* DESCRIPTION
*
* This function can be used to configure the UART driver.
*
* If this function is not called, the UART may be started with the default
* configuration.
* If this function is called, it should be called before Uartdrv_Start is
* called to initialise the driver.
*
* RETURNS
* TRUE if the configuration was successful.
*
*/
void UartDrv_Configure(unsigned long theBaudRate, char * theComPortString)
{
baudRate = theBaudRate;
strcpy(comPortString, theComPortString);
}
/*----------------------------------------------------------------------------*
* NAME
* UartDrv_Start
*
* DESCRIPTION
*
* This function is called to start the UART driver.
*
* RETURNS
* TRUE: the UART was successfully started, otherwise FALSE
*
*******************************************************************************/
bool_t UartDrv_Start(void)
{
DWORD threadId;
if (!init())
{
return FALSE;
}
/* tx and rx threads */
txThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) txThreadFunc, NULL, 0, &threadId);
if(txThread == INVALID_HANDLE_VALUE)
{
errorHandler(__LINE__, __FILE__, "Thread create failure");
return(FALSE);
}
rxThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rxThreadFunc, NULL, 0, &threadId);
if(rxThread == INVALID_HANDLE_VALUE)
{
errorHandler(__LINE__, __FILE__, "Thread create failure");
return(FALSE);
}
return TRUE;
}
void UartDrv_Stop(void)
{
DWORD threadExitCode;
SetEvent(txCloseDownEvent);
SetEvent(rxCloseDownEvent);
while (WaitForSingleObject(txDownEvent, INFINITE) != WAIT_OBJECT_0)
{
printf("WaitForSingleObject(txDownEvent, INFINITE) NOT SIGNALED????\n");
}
do
{
if (!GetExitCodeThread(txThread, &threadExitCode))
{
printf("GetExitCodeThread failed!\n");
break;
}
else
{
if (threadExitCode == STILL_ACTIVE)
{
Sleep(0);
}
}
} while (threadExitCode == STILL_ACTIVE);
CloseHandle(newTxDataEvent);
CloseHandle(txCloseDownEvent);
CloseHandle(txDownEvent);
CloseHandle(txThread);
while (WaitForSingleObject(rxDownEvent, INFINITE) != WAIT_OBJECT_0)
{
printf("WaitForSingleObject(rxDownEvent, INFINITE) NOT SIGNALED????\n");
}
do
{
if (!GetExitCodeThread(rxThread, &threadExitCode))
{
printf("GetExitCodeThread failed!\n");
break;
}
else
{
if (threadExitCode == STILL_ACTIVE)
{
Sleep(0);
}
}
} while (threadExitCode == STILL_ACTIVE);
CloseHandle(rxCloseDownEvent);
CloseHandle(rxDownEvent);
CloseHandle(dataReadEvent);
CloseHandle(rxThread);
CloseHandle(comHandle);
DeleteCriticalSection(&rxMutex);
DeleteCriticalSection(&txMutex);
}
/***********************************************************************
* RETURN
* Return FALSE if Tx buffer overflow (and *num_send = 0).
*
*/
bool_t UartDrv_Tx(uint8_t *theData, unsigned len, uint16_t *numSend)
{
uint16_t size;
#ifdef DEBUG_ENABLE
{
int i;
printf("TX[%02d]: ", len);
for (i=0;i<(int)len;i++)
{
printf("%02x ", theData[i]);
}
printf("\n");
}
#endif
*numSend = 0;
EnterCriticalSection(&txMutex);
size = txSize;
LeaveCriticalSection(&txMutex);
/* check if enough space in buffer for new data - if not return FALSE */
if (len + size > TX_BUF_MAX_SIZE)
{
errorHandler(__LINE__, __FILE__, "buffer full in uart tx");
return FALSE;
}
if (txIn + len > TX_BUF_MAX_SIZE)
{
uint16_t remainingLength;
memcpy(&txBuf[txIn], theData, TX_BUF_MAX_SIZE - txIn);
remainingLength = len - (TX_BUF_MAX_SIZE - txIn);
memcpy(txBuf, &theData[TX_BUF_MAX_SIZE - txIn], remainingLength);
txIn = remainingLength;
}
else
{
memcpy(&txBuf[txIn], theData, len);
if (txIn + len == TX_BUF_MAX_SIZE)
{
txIn = 0;
}
else
{
txIn += (uint16_t) len;
}
}
*numSend = len;
EnterCriticalSection(&txMutex);
txSize = txSize + (*numSend);
LeaveCriticalSection(&txMutex);
/* signal tx thread that new data has arrived */
SetEvent(newTxDataEvent);
return TRUE;
}
/*----------------------------------------------------------------------------*
* NAME
* UartDrv_GetTxSpace
*
* DESCRIPTION
* Obtain amount of space available in UART. Should be able to write at
* least this number of chars in a call to UartDrv_Tx().
*
* RETURNS
* The number of characters that can be written to the UART.
*
*/
uint16_t UartDrv_GetTxSpace(void)
{
uint16_t size;
EnterCriticalSection(&txMutex);
size = TX_BUF_MAX_SIZE - txSize;
LeaveCriticalSection(&txMutex);
return size;
}
/***********************************************************************
* NAME
* UartDrv_GetRxAvailable
*
* DESCRIPTION
* Obtain the number of received characters available in UART. Should be
* able to read at least this number of chars in a call to UartDrv_Rx().
*
* NOTE: if there is a 'wrap around' only the number of bytes up to the limit can
* be read but the number of bytes available may be higher
*
* RETURNS
* The number of characters that can be read from the UART.
*
*/
uint16_t UartDrv_GetRxAvailable(void)
{
uint16_t theSize;
EnterCriticalSection(&rxMutex);
theSize = rxSize;
LeaveCriticalSection(&rxMutex);
return theSize;
}
/*----------------------------------------------------------------------------*
* NAME
* UartDrv_Reset
*
* DESCRIPTION
*
* This function is called to reset the UART driver. The transmit and
* receive buffers are flushed.
*
* NOTE: the UART configuration does NOT change.
*
* RETURNS
* None
*
*/
void UartDrv_Reset(void)
{
/* clear any data in the in/out buffers */
clearBuffer();
}
void UartDrv_Rx(uint8_t *in_buf, int buf_len, int *in_len)
{
unsigned bytesConsumed;
uint16_t noOfBytes;
*in_len = 0;
EnterCriticalSection(&rxMutex);
noOfBytes = rxSize;
LeaveCriticalSection(&rxMutex);
#ifdef MAX_BYTES_TO_ABCSP
if (noOfBytes > MAX_BYTES_TO_ABCSP)
{
noOfBytes = MAX_BYTES_TO_ABCSP;
}
#endif
if (noOfBytes > (RX_BUF_MAX_SIZE - rxOut))
{
noOfBytes = (RX_BUF_MAX_SIZE - rxOut);
}
#ifdef DEBUG_ENABLE
if (noOfBytes>0)
{
int i;
printf(" RX[%02d]: ", noOfBytes);
for (i=0;i<(int)noOfBytes;i++)
{
printf("%02x ", rxBuf[rxOut+i]);
}
printf("\n");
}
#endif
//Consume data here
//Pls ensure the buffer size is enough to fix in data
if (noOfBytes > (uint16_t)buf_len)
noOfBytes = buf_len;
memcpy((void *)in_buf, &rxBuf[rxOut], noOfBytes);
*in_len = noOfBytes;
bytesConsumed = noOfBytes;
//Mark data was read, delete from queue
rxOut = rxOut + bytesConsumed;
if (rxOut >= RX_BUF_MAX_SIZE)
{
rxOut = 0x00; /* Buffer start from beginning*/
}
EnterCriticalSection(&rxMutex);
rxSize = rxSize - bytesConsumed;
LeaveCriticalSection(&rxMutex);
if (bytesConsumed > 0)
{
SetEvent(dataReadEvent);
}
if (rxSize)
{
//still got data inside
}
}
#if 0
int WriteBuffer(unsigned char *buffer,unsigned long numToWrite)
{
OVERLAPPED wOverlap = gUUTCom.writeOverlap;
unsigned long numOfWrite;
int error;
// ClearComBuffer();
WaitForSingleObject(hMutex, INFINITE);
if (WriteFile(commHandle,buffer,numToWrite,&numOfWrite,&wOverlap) == 0)
{
if (GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult( commHandle,
&wOverlap, &numOfWrite, TRUE ))
{
error = GetLastError();
if(error == ERROR_IO_INCOMPLETE)
// normal result if not finished
continue;
else
{
break;
}
}
}
else
{
printf("\n\n Write error!\n\n");
return COM_FAILURE;
}
}
ReleaseMutex(hMutex);
return COM_SUCCESS;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -