From: ScottMcP [MVP] on
On May 30, 1:39 pm, bernd <bernd.schuste...(a)googlemail.com> wrote:
> > A transmit thread and a receive thread for each com port is a good plan..
>
> Is this always a good plan independent how many com ports I`ve
> installed? What`s about the performance (using only one processor)?
>
> I mean in my case there`s only one transmit thread (sending some
> message coming via ethernet to the com port) at the same time
> possible, because the ethernet stream is serial. But it is always
> possible to get some data at different com ports at the same time.
>
> I`m creating the ui-thread with AfxBeginThread.

COM ports are slow. Seems better to me to be able to transmit
simultaneously on more than one of them concurrently. For anything up
to maybe 32 ports or so the impact of one thread per output port
should be rather miniscule at COM port speeds. But this is a minor
issue, and if you prefer doing all the writes in one thread I don't
see any problem with that.


>
> Another question: how is it possible to get the com-port number if I
> receive some data? I`m using the whole function from Mr. Newcomer
> (http://www.flounder.com/serial.htm)?Each tx ethernet packets has an
> information from which com port the data was received.
>
> m_serialWriteThread->parms = new CSerialPort(m_hComm, AfxGetMainWnd(),
> shutdown);
>
> With HANDLE port = this->parms->hCom; I only get the handle
>
> best regards

The COM read thread uses PostMessage to pass received data to the main
thread. You can pass the COM port number as part of that message:

CString* s = new CString(....);
PostMessage(UWM_DATA_READ, (WPARAM)s, (LPARAM)port_number);
From: Joseph M. Newcomer on
See below...
On Sun, 30 May 2010 11:20:26 -0700 (PDT), "ScottMcP [MVP]" <scottmcp(a)mvps.org> wrote:

>On May 30, 1:39�pm, bernd <bernd.schuste...(a)googlemail.com> wrote:
>> > A transmit thread and a receive thread for each com port is a good plan.
>>
>> Is this always a good plan independent how many com ports I`ve
>> installed? What`s about the performance (using only one processor)?
>>
>> I mean in my case there`s only one transmit thread (sending some
>> message coming via ethernet to the com port) at the same time
>> possible, because the ethernet stream is serial. But it is always
>> possible to get some data at different com ports at the same time.
>>
>> I`m creating the ui-thread with AfxBeginThread.
>
>COM ports are slow. Seems better to me to be able to transmit
>simultaneously on more than one of them concurrently. For anything up
>to maybe 32 ports or so the impact of one thread per output port
>should be rather miniscule at COM port speeds. But this is a minor
>issue, and if you prefer doing all the writes in one thread I don't
>see any problem with that.
****
This is pretty much how I would do it, except I wouldn't worry too much about the number
of ports.

If you start it with AfxBeginThread, as I pointed out, you do not need the thread ID for
anything, because you will use CWinThread::PostThreadMessage and therefore there's nothing
you need to do special to get it.
****
>
>
>>
>> Another question: how is it possible to get the com-port number if I
>> receive some data? I`m using the whole function from Mr. Newcomer
>> (http://www.flounder.com/serial.htm)?Each tx ethernet packets has an
>> information from which com port the data was received.
****
It is your responsibility to identify the information you need. In my example, I
PostMessage a length and pointer, but you could create a little object on the heap that
had the length, pointer, and any information you need to identify the source of the data.
There's nothing that limits what you transmit to the receiving thread.
*****
>>
>> m_serialWriteThread->parms = new CSerialPort(m_hComm, AfxGetMainWnd(),
>> shutdown);
>>
>> With HANDLE port = this->parms->hCom; I only get the handle
>>
****
That's right. If you want anything else, you have to provide it.
****
>> best regards
>
>The COM read thread uses PostMessage to pass received data to the main
>thread. You can pass the COM port number as part of that message:
>
>CString* s = new CString(....);
>PostMessage(UWM_DATA_READ, (WPARAM)s, (LPARAM)port_number);
***
Or you can do

CMyStuff * d = new CMyStull(length, data, port_number);
wnd->PostMessage(UWM_DATA_READ, (WPARAM)d);


The point is, YOU get to define what is in that message! If all you need is a length and
pointer, you can use WPARAM and LPARAM; if you need more, you put more into what you pass
to the thread, and it is entirely your decision as to what you put there.
joe
****
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: bernd on
thanks for the answers.


/* transmit eth-messages to the specific com port (is working) */
unsigned char* buffer=new unsigned char[400];
memcpy((void *)&buffer[0], (void *)&ptr->Data[0], 400);
m_Ports[number].m_serialWriteThread-
>PostThreadMessageA(UWM_SEND_DATA2, (WPARAM)&buffer, 400);

void CSerialWriter::OnSendData(WPARAM wParam, LPARAM lParam)
{
unsigned char * schar = (unsigned char *)wParam;
UINT length = strlen((const char *)wParam); //<- 3 instead of 400

BOOL ok = ::WriteFile(parms->hCom,(unsigned char
*)schar,lParam,&bytesWritten,&ovl);
//....

delete [] schar;
}

How can I delete the unsigned char array at the end of the
OnSendData() function?


best regards
Bernd
From: Faisal on
On May 31, 12:55 pm, bernd <bernd.schuste...(a)googlemail.com> wrote:
> thanks for the answers.
>
> /* transmit eth-messages to the specific com port (is working) */
> unsigned char* buffer=new unsigned char[400];
> memcpy((void *)&buffer[0], (void *)&ptr->Data[0], 400);

You can write this simpler
memcpy( buffer, ptr->Data, 400);

> m_Ports[number].m_serialWriteThread->PostThreadMessageA(UWM_SEND_DATA2, (WPARAM)&buffer, 400);

Here you are passing the address of buffer. No need for this
You can have
m_Ports[number].m_serialWriteThread->PostThreadMessage(UWM_SEND_DATA2,
(WPARAM)buffer, 400);

>
> void CSerialWriter::OnSendData(WPARAM wParam, LPARAM lParam)
> {
> unsigned char * schar = (unsigned char *)wParam;
> UINT length = strlen((const char *)wParam);   //<- 3 instead of 400

Because you passed the wrong pointer (&buffer).
>
> BOOL ok = ::WriteFile(parms->hCom,(unsigned char
> *)schar,lParam,&bytesWritten,&ovl);
> //....
>
> delete [] schar;
>
> }
>
> How can I delete the unsigned char array at the end of the
> OnSendData() function?

>
> best regards
> Bernd

From: Scott McPhillips [MVP] on
"bernd" <bernd.schuster12(a)googlemail.com> wrote in message
news:90e19db7-d631-4540-aff1-243ee19d2b5f(a)y12g2000vbr.googlegroups.com...
> thanks for the answers.
>
>
> /* transmit eth-messages to the specific com port (is working) */
> unsigned char* buffer=new unsigned char[400];
> memcpy((void *)&buffer[0], (void *)&ptr->Data[0], 400);
> m_Ports[number].m_serialWriteThread-
>>PostThreadMessageA(UWM_SEND_DATA2, (WPARAM)&buffer, 400);

The &buffer is the address of the pointer, not the address of the buffer.
Use buffer, not &buffer

>
> void CSerialWriter::OnSendData(WPARAM wParam, LPARAM lParam)
> {
> unsigned char * schar = (unsigned char *)wParam;
> UINT length = strlen((const char *)wParam); //<- 3 instead of 400
>
> BOOL ok = ::WriteFile(parms->hCom,(unsigned char
> *)schar,lParam,&bytesWritten,&ovl);

Why write 400 bytes when strlen has determined there are only 3 bytes
received?

> //....
>
> delete [] schar;
> }
>
> How can I delete the unsigned char array at the end of the
> OnSendData() function?

delete [] schar is the correct way to delete the buffer.

--
Scott McPhillips [VC++ MVP]