Click to See Complete Forum and Search --> : problem with reading serial port


Nawar
May 23rd, 2006, 10:38 PM
hi ..Im writing a multithreaded program in borland c++ builder 6 that communicate with serial port..readFile function is on a seperate thread and its called ( the thread) by void __fastcall read_thrd::Execute() (which replace the thread function..)..so how can I write a function that reads the serial port automatically when there is something??..(how to get the serial port status(or whatever) and react to it?)

there are some functions like WaitForSingleObject ,SetCommMask and WaitCommEvent, but I dont know how to use them properly(where to use them? in the reading thread or the main thread?and which flag to use?)

Execute() could be controled by Resume() - will resume its execution- and Suspend() - will pause and suspend its execution- and those two functions are the way to communicate with the thread from the main thread -in addition to Terminate() - , so I can write my code in execute() or in other function and then call it.

now my code it as simple as this: (Im using a butten to call resume)


//----------------------------------------------------------------------------------------------
//thread is suspended when created
void __fastcall read_thrd::Execute()
{
FreeOnTerminate = true;
while(!Terminated)
{
ReadFile(Form1->m_hCom, &(Form1->sBuffer), 128, &(Form1->iBytesWritten), &osReader) ;
Suspend();
}

if(Terminated)
{
void __endthread(void);
}
}
//----------------------------------------------------------------------------------------------
I need to replace it ..so I dont have to click the butten to read the comm port..can you help??please?

Nawar
May 25th, 2006, 08:58 PM
Hi Ive posted a thread titled: (problem with reading serial port) if that could help you..Im doing a two threads program the main one is in charge of user interface and write toport operations and the second oen is in charge with reading the serial port...
this is the reading thread code

void __fastcall read_thrd::Execute()
{ FreeOnTerminate = true;

OVERLAPPED osRead = {0};
DWORD dwCommEvent;
DWORD iBytesRead;
DWORD BytesToRead = 128;

osRead.hEvent= CreateEvent(NULL,TRUE,NULL,NULL);
if (!SetCommMask(Form1->m_hCom, EV_RXCHAR))
{
wsprintfA(Form1->sBuffer, "LastError = %d", GetLastError());
MessageBoxA(0, Form1->sBuffer, "SetCommMask() Failed", MB_OK);

}

while(!Terminated)
{ dwCommEvent = NULL;
if (!WaitCommEvent(Form1->m_hCom, &dwCommEvent, 0))
{
wsprintfA(Form1->sBuffer, "LastError = %d", GetLastError());
MessageBoxA(0, Form1->sBuffer, "WaitCommEvent() Failed", MB_OK);
break;
}

if (dwCommEvent & EV_RXCHAR)
{ ReadFile(Form1->m_hCom, &Form1->sBuffer, BytesToRead, &iBytesRead, &osRead);

FlushFileBuffers(Form1->m_hCom);

}
}
void __endthread(void);
}

now lets say that in order to do an operation i need so send a series of commands to serial port and receive answer to each one of them..
how can i synchronize the writing and reading between threads to it doesnt start writing new command untill it gets the answer from the device??
and what do you think about the code above??

Andreas Masur
May 25th, 2006, 09:01 PM
[ Merged threads ]

kirants
May 25th, 2006, 10:39 PM
now lets say that in order to do an operation i need so send a series of commands to serial port and receive answer to each one of them..
how can i synchronize the writing and reading between threads to it doesnt start writing new command untill it gets the answer from the device??
and what do you think about the code above??
You wouldn't use threads then, since basically, your operations are now sequential.
However, if your architecture is such that the reads happen in one thread and writes in another, you would have to synchronize for this sequential operations by having some kind of event signalling. Something like below:

Write thread -> ready to write to serial port
Clear an event ( manual reset event created using CreateEvent ) using ResetEvent
Write to serial port
Read thread -> waits on the event using WaitForSingleObject
Read thread -> processes read data
When succeeded -> pushes another item to the WriteThread's queue.


There could be very many ways.. but you would need to give more details in that case.

Nawar
May 26th, 2006, 02:34 AM
Im using a threaded program because:
1.almost where ever I go in the net they recommand a threaded programfor this kind of job...
2.if I do read operation from the main thread it will block and the user wont be able to use the program (click the buttons) untill it unblock
3. Im doing this program to deal with GSM modem so in some cases the modem may not reply immediatlly..(so its might be blocked for long times)
4.Ive spent lots of time learning multithreading..and Im not going back now.

now..i said that I should do some kind of sync between threads,do you mean using fOnRead fOnWrite and stuff like that?

what about using ( WaitForMultipleObjects)..from searching I saw few codes using OVERLAPPED osWrite ,osRead and osStatus(or osEvent) and Im confused about where to and how to use them??