Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Serial Port WriteFile Hangs

406 views
Skip to first unread message

Jacob Tuowski

unread,
Jun 22, 2004, 11:50:03 AM6/22/04
to
Hello,

I'm hoping that someone here can help me. I've written a simple application
that opens COM1 and does some simple writes and reads over the serial port
to a device in Windows XP Pro. The device on the other end runs fine in
Hyperterm, so I know my connection and cable are not the problem. Also, I've
been using Serial Monitor Lite from HHD software and haven't seen any data
transmitted. The problem is that WriteFile hangs everytime. I setup
everything, but still have the problem. Please help. Thanks in advance.

#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <wsipx.h>
#include <string.h>
#include <stdlib.h>

#define DATA_BUFFER_SIZE 2048

static int SendData( char c);
static DWORD WINAPI SerialRecvThread( PVOID ptr );
static HANDLE hCom, hThread, hStdIn = 0, hStdOut = 0;
static DWORD dwEvtMask = 0;
static DCB dcb;
char buffer[4096];

int main()
{
BOOLEAN cmdComplete = FALSE;
DWORD dwInputEvents; /* number of events actually read */
DWORD dwMode;
INPUT_RECORD inputBuffer;
CONSOLE_CURSOR_INFO cci; /* used when turning off the cursor */
CONSOLE_SCREEN_BUFFER_INFO csbi; /* used to get cursor position */

// Attempt to open the comm port.
hCom = CreateFile( "COM1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL );

if( hCom == INVALID_HANDLE_VALUE )
{
printf( "CreateFile failed %d\n", GetLastError() );
goto TERMINATE;
}

// Set event mask
if( ! SetCommMask( hCom, EV_RXCHAR ) )
{
printf( "SetCommMask failed %d\n", GetLastError() );
goto TERMINATE;
}

// Set buffer sizes
if( ! SetupComm( hCom, 4096, 4096 ) )
{
printf( "SetupComm failed: %d\n", GetLastError() );
goto TERMINATE;
}

// Purge queues
if( ! PurgeComm( hCom,
(PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR) ) )
{
printf( "PurgeComm failed: %d\n", GetLastError() );
goto TERMINATE;
}

// Get the current comm port settings from the system.
if( ! GetCommState( hCom, &dcb ) )
{
printf( "GetCommState failed: %d\n", GetLastError() );
goto TERMINATE;
}

// Set our requirements for the port.
dcb.BaudRate = 19200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = TWOSTOPBITS;

// Send the port configuration back to the system.
if( ! SetCommState( hCom, &dcb ) )
{
printf( "SetCommState failed: %d\n", GetLastError() );
goto TERMINATE;
}

// Create recv thread
if( ( hThread = CreateThread( 0, 0, SerialRecvThread, NULL, 0, NULL) ) ==
NULL)
{
printf( "Thread start failed %d\n", GetLastError() );
goto TERMINATE;
}

// Setup console
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
if (csbi.dwCursorPosition.X | csbi.dwCursorPosition.Y)
{
FreeConsole();
AllocConsole();
}

SetConsoleTitle("Serial Test");

hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
hStdIn = GetStdHandle(STD_INPUT_HANDLE);

GetConsoleMode(hStdIn, &dwMode);
SetConsoleMode(hStdIn, (dwMode & ~(ENABLE_LINE_INPUT |
ENABLE_ECHO_INPUT)) |
ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);

cci.dwSize = 100;
cci.bVisible = TRUE;
SetConsoleCursorInfo(hStdOut, &cci);

// Event loop
do
{
// read an input events from the input event queue
ReadConsoleInput(hStdIn, &inputBuffer, 1, &dwInputEvents);
switch (inputBuffer.EventType)
{
case KEY_EVENT:
if (inputBuffer.Event.KeyEvent.bKeyDown &&
inputBuffer.Event.KeyEvent.uChar.AsciiChar)
{
if( ! SendData(inputBuffer.Event.KeyEvent.uChar.AsciiChar) )
{
goto TERMINATE;
}
}
break;
case WINDOW_BUFFER_SIZE_EVENT:
//Sleep(1000);
break;
}
// If ESC - loop ends
}
while (!(inputBuffer.EventType == KEY_EVENT &&
inputBuffer.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE &&
inputBuffer.Event.KeyEvent.bKeyDown));

TERMINATE:
// Close the port.
CloseHandle( hCom );

return( 0 );
}

static DWORD WINAPI SerialRecvThread( PVOID ptr )
{
ULONG error = 0;
ULONG count = 1;
DWORD written = 0;
DWORD chars = 0;
ULONG i = 0;
char buffer[DATA_BUFFER_SIZE];

while( TRUE )
{
if( ! WaitCommEvent( hCom, &dwEvtMask, NULL ) )
{
error = GetLastError();
printf("RecvThread error - WaitCommEvent failed: %u\n", error );
return( 1 );
}
if( ! ReadFile( hCom, buffer, DATA_BUFFER_SIZE, &count, NULL ) )
{
error = GetLastError();
printf("RecvThread error - ReadFile failed: %u\n", error );
return( 1 );
}
chars = 0;
do
{
WriteConsole (hStdOut, buffer, count, &written, 0);
chars += written;
}
while (chars < count);
} // while

return( 0 );
}

static int SendData( char c )
{
ULONG error = 0;
ULONG written;

if( ! WriteFile( hCom, &c, 1, &written, NULL ) )
{
error = GetLastError();
printf("WriteFile failed: %u\n", error );
return( 0 );
}

return( 1 );
}

Andreas Marschall [MVP TAPI]

unread,
Jun 22, 2004, 12:16:49 PM6/22/04
to
"Jacob Tuowski" <nom...@nospam.com> schrieb im Newsbeitrag
news:10dgl99...@corp.supernews.com...

> I'm hoping that someone here can help me. I've written a simple application
> that opens COM1 and does some simple writes and reads over the serial port
> to a device in Windows XP Pro. The device on the other end runs fine in
> Hyperterm, so I know my connection and cable are not the problem. Also, I've
> been using Serial Monitor Lite from HHD software and haven't seen any data
> transmitted. The problem is that WriteFile hangs everytime. I setup
> everything, but still have the problem. Please help. Thanks in advance.

Jacob,
it seem that you don't use TAPI - that's what this newsgroup is about.

Take a look at the TapiComm sample from P-SDK.
See my TAPI and TSPI FAQ:
Q: Is there any sample code available ?
http://www.i-b-a-m.de/Andreas_Marschall's_TAPI_and_TSPI_FAQ.htm#_Q:_Is_there

--
Best Regards
Andreas Marschall
Microsoft MVP for TAPI / Windows SDK
TAPI / TSP Developer and Tester
http://www.I-B-A-M.de/Andreas_Marschall's_TAPI_and_TSPI_FAQ.htm
* Please post all messages and replies to the newsgroup so all may
* benefit from the discussion. Private mail is usually not replied to.
* This posting is provided "AS IS" with no warranties, and confers no rights.


William DePalo [MVP VC++]

unread,
Jun 22, 2004, 12:32:18 PM6/22/04
to
"Jacob Tuowski" <nom...@nospam.com> wrote in message
news:10dgl99...@corp.supernews.com...

> I'm hoping that someone here can help me. I've written a simple
application
> that opens COM1 and does some simple writes and reads over the serial port
> to a device in Windows XP Pro.

Andreas is right, this group is only marginally related to serial
communication issues.

That said, in the past I have used the little HACK below to demonstrate to
newbies soome of the basics of serial communication under Win32. It
demonstrates setting both some basic parameters and timeout behavior as well
as one way to overlap reads and writes. As a test it sends the Hayes
"identify" command to my modem on COM3 and displays the response.

I hope it helps.

Regards,
Will

int main(int argc, char **argv)
{
char szBuffer[80];
DCB dcb = {0};
DWORD dwRead, dwWritten;
HANDLE hComm;
OVERLAPPED ovlr = {0}, ovlw = {0};
COMMTIMEOUTS cto;

// Create events for overlapped operation

ovlr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ovlw.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

// Open the port

hComm = CreateFile("\\\\.\\COM3", GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);

// Get the state of the device and modify it

dcb.DCBlength = sizeof(dcb);
GetCommState(hComm, &dcb);
dcb.BaudRate = CBR_9600;
SetCommState(hComm, &dcb);

// Set the timeout parameters

cto.ReadIntervalTimeout = 1000;
cto.ReadTotalTimeoutConstant = 1000;
cto.ReadTotalTimeoutMultiplier = 1000;
cto.WriteTotalTimeoutConstant = 1000;
cto.WriteTotalTimeoutMultiplier = 1000;

SetCommTimeouts(hComm, &cto);

// Send a command and receieve a response. Note that
// we post the receive in advance of sending the
// command in order not to miss anything

printf("\r\nSending: ATI1\r\n");

ReadFile (hComm, szBuffer, sizeof(szBuffer), &dwRead, &ovlr);
WriteFile(hComm, "ATI1\r", strlen("ATI1\r"), &dwWritten, &ovlw);

// Wait for the receive to complete and display the response

if ( GetOverlappedResult(hComm, &ovlr, &dwRead, TRUE) )
{
szBuffer[dwRead] = 0;
printf("Received: %s\r\n", szBuffer);
}

// Close the device

CloseHandle(hComm);

return 0;
}


0 new messages