🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
6 messages
6 total messages Started by JD Thu, 15 Jun 2006 18:19
Com port error
#3472
Author: JD
Date: Thu, 15 Jun 2006 18:19
18 lines
1432 bytes
I'm trying to setup a test application that mimics a device
that would be connect to a com port so that I can test a
thread that collects data from the device.

The problem that I'm having is that I want the thread to use
WaitCommEvent which means that when I open the port using
CreateFile, I must specify FILE_FLAG_OVERLAPPED for the
dwFlagsAndAttributes parameter.

When the port is opened this way, WriteFile fails with an error
code of 997 which translates to "Overlapped I/O operation is in
progress".

Does anyone have any thoughts on how I might accomplish what I
want (just a small test that will write data to the port)?

~ JD
Re: Com port error
#3470
Author: Remy Lebeau (TeamB)
Date: Thu, 15 Jun 2006 18:26
49 lines
2407 bytes
"JD" <nospam@nospam.com> wrote in message
news:4491a4c2$1@newsgroups.borland.com...

> The problem that I'm having is that I want the thread to use
> WaitCommEvent which means that when I open the port using
> CreateFile, I must specify FILE_FLAG_OVERLAPPED for the
> dwFlagsAndAttributes parameter.

Not true.  WaitCommEvent() works on non-overlapped ports as well.  If you do
not specify FILE_FLAG_OVERLAPPED, then you have to pass NULL to any function
that has an OVERLAPPED parameter.

> When the port is opened this way, WriteFile fails with an error
> code of 997 which translates to "Overlapped I/O operation is in
> progress".

As it should be.  997 is ERROR_IO_PENDING.  That is not an error.  You just
need to call GetOverlappedResult() to wait for the actual work to finish,
ie:

    DWORD dwWritten;

    if( !WriteFile(hPort, ..., &dwWritten, &overlapped) )
    {
        if( GetLastError() != ERROR_IO_PENDING )
        {
            // an actual error occured, do something ....
            return;
        }

        GetOverlappedResult(hPort, &overlapped, &dwWritten, TRUE);
    }

    // use dwWritten as needed ...

The thing about GetOverlappedResult() is that you can set the bWait
parameter to FALSE instead if you want to go do other things while you wait
for the data to be written, ie:

    write to port ...
    do some work ...
    check overlapped result ...
    do some more work ...
    check overlapped result ...
    etc ...


Gambit
Re: Com port error
#3474
Author: JD
Date: Fri, 16 Jun 2006 15:19
37 lines
2157 bytes
"Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> wrote:
>
> WaitCommEvent() works on non-overlapped ports as well.

After some searching, it's been decided that the thread should
not use WaitCommEvent but I can use WaitForSingleObjectEx. I
wasn't there for that one so what ever. I just want a test bed
for testing the thread and it escapes me.

What I'm trying to do now is open the port twice - once for
reading and another for writing but on the second call to
CreateFile, I get an Access denied error:

    WCom = ::CreateFile( TEXT("COM1"), 
                         GENERIC_WRITE,
                         FILE_SHARE_READ,
                         NULL, 
                         OPEN_EXISTING,
                         0,
                         NULL
                       );


    RCom = ::CreateFile( TEXT("COM1"),
                         GENERIC_READ,
                         0,
                         NULL,
                         OPEN_EXISTING,
                         0,
                         NULL
                       );

Please note that I've tried what seems to me to be all logical
combinations of the dwDesiredAccess and dwShareMode.

~ JD
Re: Com port error
#3471
Author: Remy Lebeau (TeamB)
Date: Fri, 16 Jun 2006 16:55
41 lines
2148 bytes
"JD" <nospam@nospam.com> wrote in message
news:4492cbf9$1@newsgroups.borland.com...

> After some searching, it's been decided that the thread
> should not use WaitCommEvent

Why not?  That is the correct way to wait for events on a COM port.  Have
you read the MSDN articles on working with communication ports yet?  I
strongly suggest that you do so.

    Communications Resources

http://msdn.microsoft.com/library/en-us/devio/base/communications_resources.asp

    Serial Communications in Win32
    http://msdn.microsoft.com/library/en-us/dnfiles/html/msdn_serial.asp

The second article has a lot of sample source code in it.

> What I'm trying to do now is open the port twice

You can't do that.  A COM port can only be opened once.

> once for reading and another for writing

You would have to open it once for both reading and writing at the same
time:

    WCom = ::CreateFile( TEXT("COM1"), GENERIC_READ | GENERIC_WRITE, 0,
...);

Notice above that the sharing rights must also be set to 0 for exclusive
access.  You cannot share a COM port.

> but on the second call to CreateFile, I get an Access denied error:

As you should be.


Gambit
Re: Com port error
#3477
Author: JD
Date: Sat, 17 Jun 2006 18:50
21 lines
1555 bytes
"Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> wrote:
>
>> After some searching, it's been decided that the thread
>> should not use WaitCommEvent
>
> Why not?

I'm not sure exactly. I think it had something to do with
fear that the thread would get deadlocked if no data ever
came across. I haven't researched it yet but ISTM that
unless one can set a timeout for WaitCommEvent, the thread
won't ever terminate.

> Have you read the MSDN articles on working with communication
> ports yet?  I strongly suggest that you do so.

I've looked at both links yes (thank you), but I still can't
get a simple test to work!

~ JD
Re: Com port error
#3478
Author: Remy Lebeau (TeamB)
Date: Sat, 17 Jun 2006 21:29
28 lines
2108 bytes
"JD" <nospam@nospam.com> wrote in message
news:44944f06@newsgroups.borland.com...

> I'm not sure exactly. I think it had something to do with
> fear that the thread would get deadlocked if no data ever
> came across.

That is what Overlapped I/O is for.  Besides that, you can alternatively use
SetCommTimeouts() to set the reading/writing timeouts on the COM port so
that code cannot deadlock forever.

> I haven't researched it yet but ISTM that unless one can set
> a timeout for WaitCommEvent, the thread won't ever terminate.

You would need to use Overlapped I/o in order for WaitCommEvent() to support
a timeout.

> I've looked at both links yes (thank you), but I still can't
> get a simple test to work!

What EXACTLY have you tried so far that does not work for you?  I find those
articles, especially "Serial Communications in Win32", to be very useful.
I've written entire reading/writing schemes based on the information in that
one article.


Gambit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads