Re: Serial thread continued
On Aug 16, 10:31 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Sat, 16 Aug 2008 18:01:13 -0700 (PDT), Kahlua <edward.freder...@verizo=
n.net> wrote:
I have managed to make some headway on the serial thread.
I have a button on my dialog that sends a byte to a microcontroller.
The micro responds by sending a 10h followed by 33 bytes.
I have tested the micro's response with hyperterm so I know it works.
Now when the 10h comes in it does seem to read the 33 bytes that
follow'd.
BUT, before the PostMessage I get the error "Error reading data".
****
Get rid of the WaitCommEvent and use WaitForMultipleObjects on a shutdown=
event and the
event in the OVERLAPPED structure.
Note that it is completely meaningless to report "ReadFile Failed". Th=
e ONLY meaningful
report is "ReadFile failed and GetLastError returned <value here>". If=
you fail to
GetLastError, you have failed to test correctly the result of ReadFile. =
****>When I click OK on the error messagebox all the data did appear as
expected.
How do I find out what the error was?
****
GetLastError, as documented in the discussion of ReadFile
****>Also after the data appears another MessageBox show "Error 1 reading
port".
This is appearing after the data shows and no more requests are made
for more.
****
a. Do not use AfxMessageBox in a thread
b. Report the error of GetLastError in the TRACE statement
****
Below is the current routine.
Please just fix it or explain how to fix it clearly.
UINT SerialThread( LPVOID Param ) //Thread to monitor serial activity
{
HWND hDlg = (HWND)Param;
****
Note you could also use a CWnd * here, and you wouldn't have to use ::Pos=
tMessage
****
OVERLAPPED ovl = {0};
BYTE chread;
DWORD dwRead;
DWORD dwEventMask;
int i;
if(!SetCommMask(hCom, EV_RXCHAR))
AfxMessageBox("Error setting ComMask");
BOOL running = TRUE;
while(running){
if(WaitCommEvent(hCom, &dwEventMask, NULL)){
if (!ReadFile (hCom, &chread, 1, &dwRead, &ovl)){
AfxMessageBox("Error 1 reading comm port");
}
if (chread == 0x10){
for (i=0; i<33; i++){
if (!ReadFile (hCom, &chread, 1, &dwRead, &ovl)){
AfxMessageBox("Error reading data");
****
Since you did not call ::GetLastError this message contains no useful inf=
ormation. Correct
coding would be
if(!ReadFile(...))
{
DWORD err = ::GetLastError();
TRACE(_T("Error reading data: %d\=
n"), err);
}
Note that if the error is ERROR_IO_PENDING, then you have not handled asy=
nchronous I/O
correctly, and I note that although you are using WaitCommEvent for the 0=
x10, you fail to
use it for the other ReadFile, so why do you think it is going to work co=
rrectly? It
almost certainly is returning ERROR_IO_PENDING, which is exactly what I w=
ould expect it to
do because that's how you coded it: you CANNOT expect that having receive=
d one character,
that in 0 time, the remaining 33 characters will magically appear. Bu=
t since the whole
approach of using WaitCommEvent is probably the wrong approach, and readi=
ng one character
at a time is a poor methodology, and using a global variable is a very ba=
d decision, none
of this misbehavior surprises me.
Look at my essay on serial ports. You will not find a single WaitCommE=
vent anywhere in
it; in fact, I have never used WaitCommEvent in programming serial ports =
(and I've written
a LOT of serial port code)
joe
****> }
Bar[i] = chread;
}
::PostMessage(hDlg, MY_SERIAL, (WPARAM)0, (LPARAM)0);
}
}
}
return TRUE;
}
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm- Hide quoted text -
- Show quoted text -
As usual your reply helps very little.
Your answers always point out "what not to do", but little as to "what
to do".
You allways refer to your essays.
What if I do not want to REWRITE my entire application to incorporate
all the threads you suggest.
My open serial is fine, my parameter setting is fine, and my writing
is fine.
I just want a worker thread that works, so whenever data comes in the
port I act upon it.
A different number of bytes come in depending on the 1st byte value.
I cannot simply refer to your Reader thread as it uses parts of your
Writer functions.
Also I am using VS6 and your essay doesnt.
I find it hard to believe it takes 50+ lined of code in the worker
thread just to receive a little data.
ALSO I replaced the AfxMessageBox areas with your TRACE as below.
UINT SerialThread( LPVOID Param ) //Thread to monitor serial activity
{
HWND hDlg = (HWND)Param;
OVERLAPPED ovl = {0};
BYTE chread;
DWORD dwRead;
DWORD dwEventMask;
int i;
if(!SetCommMask(hCom, EV_RXCHAR))
AfxMessageBox("Error setting ComMask");
BOOL running = TRUE;
while(running){
if(WaitCommEvent(hCom, &dwEventMask, NULL)){
if (!ReadFile (hCom, &chread, 1, &dwRead, &ovl)){
DWORD err = ::GetLastError();
TRACE(_T("Error reading data: %d\n"), err);
}
if (chread == 0x10){
for (i=0; i<33; i++){
if (!ReadFile (hCom, &chread, 1, &dwRead, &ovl)){
DWORD err = ::GetLastError();
TRACE(_T("Error reading data: %d\n"), err);
}
Bar[i] = chread;
}
::PostMessage(hDlg, MY_SERIAL, (WPARAM)0, (LPARAM)0);
}
}
}
return TRUE;
}
Now NO errors are reported but all the data is not being received.
How did this solve anything but remove the old messages?