473,735 Members | 1,875 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problems with Serial Comm Handle

Hi All,

I wrote a code to do serial communication with an equipament.
When i use the code outside of threaded class it seens work properly,
but when i put inside a class and execute a thread in the first seconds the
communication is ok, later i receive read/write error.
I?ve been in MSDN site and there i discover that the read/write error is a
INVALID_HANDLE problem. But why??? I just create the serial communication
file and use it.
Anyone can help me?

Here is the code
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class */

#ifndef _IGERENCIADOREQ UIPAMENTO_H
#define _IGERENCIADOREQ UIPAMENTO_H

#include <stdio.h>
#include <windows.h>

#define SERIAL_PARITY_N ONE 0
#define SERIAL_PARITY_O DD 1
#define SERIAL_PARITY_E VEN 2

#define SERIAL_MAX_RX 256 // Input buffer max size
#define SERIAL_MAX_TX 256 // output buffer max size
#define SERIAL_CONNECTE D 0
#define SERIAL_DISCONNE CTED 1
#define SERIAL_DATA_SEN T 2
#define SERIAL_DATA_ARR IVAL 3
#define SERIAL_RING 4
#define SERIAL_CD_ON 5
#define SERIAL_CD_OFF 6
#define SERIAL_DATA_REC V 7

#define SERIAL_SIGNAL_N BR 7

class IGerenciadorEqu ipamento;

typedef struct
{
HANDLE serialFD;
IGerenciadorEqu ipamento* pIGE;
}_SERIALCOM_ION ICS;
class IGerenciadorEqu ipamento: public IThread
{

private:
HANDLE hSerial;
char *cPortaSerial;
DWORD dwBaudRate;
BYTE byByteSize;
BYTE byTipoParidade;
bool conectado;
bool bRX_In_Progress ; // BOOL indicating if a
ReadFile is
// in progress
bool bTX_In_Progress ; // BOOL indicating if a
WriteFile is
// in progress

unsigned char pacoteIN[256];
unsigned char pacoteOUT[256];

bool bConectado;

int ConfigTimeouts( COMMTIMEOUTS mCommtimeout);
int ConfigDCB(DCB mDCB);

public:
IGerenciadorEqu ipamento(char *mcPortaSerial, DWORD mdwBaudRate,
BYTE mbyByteSize, BYTE mbyiTipoParidad e);
~IGerenciadorEq uipamento();

int AtivaEquipament o(BOOL mbIniciaThread = true);
int DesativaEquipam ento(BOOL mbFinalizaThrea d = true);
int EscreveMensagem (HANDLE hSerialCOM,unsi gned char* mcMensagem, int
miTamanho);
int LeMensagem(HAND LE hSerialCOM,unsi gned char* mcMensagem, int
miTamanho);
void PurgeSerial(voi d);
bool VerificaEstado( void);
int Run(void);
HANDLE GetSerialHND(vo id);
void OnSendRecv(void );
unsigned char *GetDadosRecebi dos(void);
unsigned char *GetDadosEnviad os(void);

int EnviaPOLLING(HA NDLE hSerialCOM);
int ConcedePrivileg io(HANDLE hSerialCOM, BYTE byEndereco);
void TraduzMens(unsi gned char *ucPacote, DWORD miTamanho);
DWORD IGerenciadorEqu ipamento::Extra iCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT);
};

//DWORD WINAPI ComSendRecv(LPV OID p);
int ComSendRecv(LPV OID p);

#endif

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class Code */

//#define STRICT
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>
#include <iostream>
#include <math.h>
#include "IGerenciadorEq uipamento.hpp"
#include "StringMethods. hpp"
#include "Consts.hpp "
#include "TipoProtocolo. hpp"

#define SIG_POWER_DOWN 0
#define SIG_READER 1
#define SIG_READ_DONE 2 // data received has been read
#define SIG_WRITER 3
#define SIG_DATA_TO_TX 4 // data waiting to be sent
#define SIG_MODEM_EVENT S 5
#define SIG_MODEM_CHECK ED 6


using namespace std;
typedef struct
{
BYTE controladora;
BYTE tentativas;
bool detectaprot;
}STRU_CONFCONTR OL;
STRU_CONFCONTRO L ConfControl;

unsigned char *IGerenciadorEq uipamento::GetD adosRecebidos(v oid)
{
return pacoteOUT;
}

unsigned char *IGerenciadorEq uipamento::GetD adosEnviados(vo id)
{
return pacoteIN;
}

int IGerenciadorEqu ipamento::Envia POLLING(HANDLE hSerialCOM)
{
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
int iTotalLido;

ZeroMemory(ucPa coteIN,3);

ucPacoteIN[0] = SYN;
ucPacoteIN[1] = '1';
ucPacoteIN[2] = 0x55;

EscreveMensagem (hSerialCOM ,ucPacoteIN,3);
iTotalLido=LeMe nsagem(hSerialC OM ,ucPacoteOUT,30 );
if (iTotalLido)
{
if ((ucPacoteOUT[0] == SYN) && (ucPacoteOUT[1] == '1') &&
(ucPacoteOUT[2] == 0xAA))
ConfControl.det ectaprot = false;
}
return iTotalLido;
}

int IGerenciadorEqu ipamento::Conce dePrivilegio(HA NDLE hSerialCOM, BYTE
byEndereco)
{
unsigned char ucPacoteIN[256];
int iTotalEscrito;

ZeroMemory(ucPa coteIN,3);

// privilegio
ucPacoteIN[0] = SYN;
ucPacoteIN[1] = byEndereco+48;
ucPacoteIN[2] = ACK;

iTotalEscrito=E screveMensagem( hSerialCOM ,ucPacoteIN,3);
return iTotalEscrito;
}

void IGerenciadorEqu ipamento::Tradu zMens(unsigned char *ucPacote, DWORD
miTamanho)
{
int iCanal;
double dLitros;
char cPulsos[8];
double dPulsos;
char parcelaPacote;
char cInd;
int iInd;
int k;

dLitros = 0;
iCanal = ((((BYTE)ucPaco te[1])-49)*8);
iInd = ucPacote[3] & 0x0F;

switch(iInd)
{
case 0:
iCanal += ((((BYTE)ucPaco te[4])-47)+100);
printf("Bomba %i ligada\n",iCana l-100);
break;
case 1:
iCanal += ((((BYTE)ucPaco te[4])-47)+100);
printf("Bomba %i desligada\n",iC anal-100);

dPulsos = 0;
k=0;
ZeroMemory(cPul sos,8);
for (int i=5;i<13;i++)
{
cPulsos[k] = ucPacote[i];
k++;
}
dPulsos = atof(cPulsos);

dLitros = round(dPulsos/1*100)/100;

if ((iCanal > 100) && (iCanal < 133))
{
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, dLitros);
}
else
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, 0.00);

break;
case 7:
printf("APM Reenergizado\n" );
break;
}
}

DWORD IGerenciadorEqu ipamento::Extra iCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT)
{
int i;
DWORD dPosETX = 0;
DWORD dPosSTX = 0;
DWORD dPosDC2 = 0;
bool bOneMoreSYN;
bool bMensTexto;
bool bContinuar = true;
DWORD dBytesToSYN;
int iTotalBytes;

iTotalBytes = 0;
dBytesToSYN = 0;
bMensTexto = false;
bOneMoreSYN = true;
dPosETX = 0;
dPosSTX = 0;
dPosDC2 = 0;

for(i=dQtdebyte s-1;(i>=0);i--)
{

if (bOneMoreSYN)
dBytesToSYN++;

switch(ucPacote IN[i])
{
case SYN:
if ((dPosETX) && (dPosSTX) && ((dPosSTX-i) == 2) && (dQtdebytes
dPosETX))

{
bMensTexto = true;
bContinuar = false;
break;
}
else
{
if ((dPosDC2) && (dPosDC2-i) == 2)
{
if ((!bOneMoreSYN) && (dBytesToSYN > 0))
{
return iTotalBytes;
}
else
{
bContinuar = false;
break;
}
}
else
{
if (!bOneMoreSYN) { return 0; }
bOneMoreSYN = false;
dPosDC2 = 0;
dPosETX = 0;
dPosSTX = 0;
}

}
break;

case DC2: dPosDC2 = i; break;
case STX: dPosSTX = i; break;
case ETX: dPosETX = i; break;
}
if (!bContinuar) break;
}

if ((i != 0xFFFF) && (ucPacoteIN[i] == SYN))
{
if (bMensTexto)
dPosETX++;
else
dPosETX = dPosDC2;

for(int j=i;j<=dPosETX; j++)
{
ucPacoteOUT[iTotalBytes] = ucPacoteIN[j];
iTotalBytes++;
}
}
return iTotalBytes;
}
IGerenciadorEqu ipamento::IGere nciadorEquipame nto(char *mcPortaSerial,
DWORD mdwBaudRate,
BYTE mbyByteSize,
BYTE mbyTipoParidade )
{
cPortaSerial = mcPortaSerial;
dwBaudRate = mdwBaudRate;
mbyTipoParidade = mbyTipoParidade ;
mbyByteSize = mbyByteSize;
hSerial = INVALID_HANDLE_ VALUE;
conectado = false;
bRX_In_Progress = false;
bTX_In_Progress = false;
ConfControl.det ectaprot = true;
ConfControl.ten tativas = 0;
ConfControl.con troladora = 0;

}

IGerenciadorEqu ipamento::~IGer enciadorEquipam ento()
{
conectado = false;
cPortaSerial = "";
dwBaudRate = 0;
byTipoParidade = SERIAL_PARITY_N ONE;
byByteSize = 0;

if (GetThreadHND() !=0)
WaitForSingleOb ject(GetThreadH ND(), 2000);

bRX_In_Progress = false;
bTX_In_Progress = false;
if (hSerial != INVALID_HANDLE_ VALUE)
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;
}

int IGerenciadorEqu ipamento::Confi gTimeouts(COMMT IMEOUTS mCommtimeout)
{

// configura os timeouts da Porta Serial
mCommtimeout.Re adIntervalTimeo ut = 20;
mCommtimeout.Re adTotalTimeoutM ultiplier = 1;
mCommtimeout.Re adTotalTimeoutC onstant = 20;
mCommtimeout.Wr iteTotalTimeout Multiplier = 5;
mCommtimeout.Wr iteTotalTimeout Constant = 5;

return SetCommTimeouts (hSerial,&mComm timeout);
}

int IGerenciadorEqu ipamento::Confi gDCB(DCB mDCB)
{
// recupera as informa??es do DCB
if (!GetCommState( hSerial,&mDCB))
{
CloseHandle(hSe rial);
return ERROR_INVALID_H ANDLE;
}
// set DCB to configure the serial port
mDCB.DCBlength = sizeof(mDCB);

/* ---------- Serial Port Config ------- */
mDCB.BaudRate = dwBaudRate;

switch(byTipoPa ridade)
{
case SERIAL_PARITY_N ONE:
mDCB.Parity = NOPARITY;
mDCB.fParity = 0;
break;
case SERIAL_PARITY_E VEN:
mDCB.Parity = EVENPARITY;
mDCB.fParity = 1;
break;
case SERIAL_PARITY_O DD:
mDCB.Parity = ODDPARITY;
mDCB.fParity = 1;
break;
}
mDCB.StopBits = ONESTOPBIT;
mDCB.ByteSize = 8;
mDCB.fBinary = 0;
mDCB.fAbortOnEr ror = 0;
mDCB.wReserved = 0;
mDCB.XonLim = 100;
mDCB.XoffLim = 100;
mDCB.XonChar = 0x0D;
mDCB.XoffChar = 0x0A;
mDCB.ErrorChar = 0;
mDCB.EofChar = 0;
mDCB.EvtChar = 0;
mDCB.wReserved1 = 0;

return SetCommState(hS erial,&mDCB);

}
int IGerenciadorEqu ipamento::Ativa Equipamento(BOO L mbIniciaThread)
{
int iErro;
DCB dcb;
int i;

COMMTIMEOUTS cto;
if (hSerial != INVALID_HANDLE_ VALUE)
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;

if (cPortaSerial != "")
{
iErro = 0;

hSerial = CreateFile(cPor taSerial, // filename
GENERIC_READ | GENERIC_WRITE, // acesso
desejado
0, // modo de
compartilhament o
NULL, // atributos
de seguran?a
OPEN_EXISTING, // disposi??o
da cria??o do arquivo
FILE_FLAG_NO_BU FFERING,
// flag de cria??o
NULL); // indica se
pode ou n?o copiar os
// atributos do
arquivo atual para outro
// arquivo
if (hSerial != INVALID_HANDLE_ VALUE)
{
bConectado = true;

// aplica os timeous
if (!ConfigTimeout s(cto))
iErro = 2;

// aplica o DCB
if (!ConfigDCB(dcb ))
iErro = 4;

}
}
else
iErro = -2;
/* --------------------------------------------- */
if (iErro > 0)
{
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;
}
else
{

HANDLE hThread1;
DWORD dThreadID1;
if(mbIniciaThre ad)
{
printf("Connect ed ! \n");

hThread1 = CreateThread(NU LL, // default
security attributes
0, // use default
stack size
(DWORD (_stdcall *)(void *))ComSendRecv,
// thread function
(void*)this, // argument to thread
function
0, // use default
creation flags
&dThreadID1) ; // returns the
thread identifier

*/

}
}

/* --------------------------------------------- */
return iErro;

}
int IGerenciadorEqu ipamento::Desat ivaEquipamento( BOOL mbFinalizaThrea d)
{
conectado = false;

if(mbFinalizaTh read)
{

}
if (hSerial != INVALID_HANDLE_ VALUE)
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;
if (this->GetThreadHND() )
{
if (WaitForSingleO bject (this->GetThreadHND() , 2000) == WAIT_TIMEOUT)
{
TerminateThread (this->GetThreadHND() , 1);
CloseHandle (this->GetThreadHND() );
}
else CloseHandle (this->GetThreadHND() );
}
CloseHandle(thi s->GetThreadHND() );

printf("Disconn ected ! \n");

}

int IGerenciadorEqu ipamento::Escre veMensagem(HAND LE hSerialCOM,unsi gned
char* mcMensagem, int miTamanho)

{
char cTXBuffer[SERIAL_MAX_RX];
DWORD iQtdebytesEscri tos;
int iTamanhoBuffer = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;


if (!bTX_In_Progre ss)
{
PurgeComm(hSeri alCOM,PURGE_TXC LEAR | PURGE_RXCLEAR);
//hCom = hSerialCOM;

iSuccess = WriteFile(hSeri alCOM,
mcMensagem,
miTamanho,
&iQtdebytesEscr itos,
NULL);

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDIN G )
printf("erro: %i , qtde: %i => WriteFile error (not pending)\
n", Error,iQtdebyte sEscritos & 0xFFFF);
}

bTX_In_Progress = false;

}

return iQtdebytesEscri tos;
}
int IGerenciadorEqu ipamento::LeMen sagem(HANDLE hSerialCOM,unsi gned char*
mcMensagem, int miTamanho)
{
DWORD iQtdebytesLidos ;
DWORD iLenMensagem = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;

ZeroMemory(mcMe nsagem,SERIAL_M AX_RX);

if (!bRX_In_Progre ss)
{
// locking reading
bRX_In_Progress = true;
//hCom = hSerialCOM;

// starting a new read
iSuccess = ReadFile(hSeria lCOM, // handle do arquivo
mcMensagem, // buffer de leitura
miTamanho, // n?mero de bytes a serem lidos
&iQtdebytesLido s, // n?mero de bytes realmente
lidos
NULL); // usado para leitura
concorrente
// da serial

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDIN G)
{
printf("erro: %i , qtde: %i => Readfile error (not pending)\
n", Error,iQtdebyte sLidos & 0xFFFF);
}
}
bRX_In_Progress = false;
}

return iQtdebytesLidos ;
}

void IGerenciadorEqu ipamento::Purge Serial(void)
{
PurgeComm(hSeri al,PURGE_TXCLEA R | PURGE_RXCLEAR);
}

bool IGerenciadorEqu ipamento::Verif icaEstado(void)
{
// return (bRX_In_Progres s || bTX_In_Progress );
}

int ComSendRecv(LPV OID p)
{
IGerenciadorEqu ipamento* pIGE;

pIGE = (IGerenciadorEq uipamento*)p;

if (pIGE !=0)
return pIGE->Run();

}

BYTE CalculaCRC(unsi gned char *msg, int qtdeBytes)
{
BYTE valor_crc = 0;

for (int i=0; i<=qtdeBytes-1;i++)
{
valor_crc += msg[i];
}
return valor_crc;
}

int IGerenciadorEqu ipamento::Run(v oid)
{
bool bDone;
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
unsigned char ucPacoteCMD[256];
int iRetry;
BYTE byPacoteCRC, byPacoteCalcCRC ;
// char *lista[3];

int iTotalLido = 0;
int iTamPacoteCMD = 0;

bDone = false;
bRX_In_Progress = false;
bTX_In_Progress = false;

GetLastError(); // just to clear any pending error

HANDLE hComm = hSerial;

char cmd[5];

while(!bDone)
{

Sleep(1000);

if (ConfControl.de tectaprot)
EnviaPOLLING(hS erial);

if (ConfControl.co ntroladora)
{
iTotalLido = LeMensagem(hSer ial ,pacoteOUT,30);
if (iTotalLido)
{
ConcedePrivileg io(hSerial,Conf Control.control adora);
ConfControl.ten tativas = 5;
}
ConfControl.ten tativas--;
if (ConfControl.te ntativas <= 0)
{
ConfControl.ten tativas = 0;
ConfControl.con troladora = 0;
}
}

ConcedePrivileg io(hSerial,0);

iRetry = 1;

while (iRetry >0)
{

iRetry--;

iTotalLido = LeMensagem(hSer ial,ucPacoteOUT ,30);
if (iTotalLido)
{
ZeroMemory(ucPa coteCMD,SERIAL_ MAX_RX);

iTamPacoteCMD = ExtraiCMD
(ucPacoteOUT,1, iTotalLido,ucPa coteCMD);
if (iTamPacoteCMD > 0)
{

ZeroMemory(ucPa coteIN,SERIAL_M AX_RX);

switch(ucPacote CMD[2])
{
case DC2:
if (isdigit(ucPaco teCMD[1]))
{
iRetry = 1;
ConcedePrivileg io(hSerial,((BY TE)ucPacoteCMD[1]
-48));
}
break;

case STX:
byPacoteCalcCRC = CalculaCRC
(ucPacoteCMD,iT amPacoteCMD-1);
byPacoteCRC = (BYTE)ucPacoteC MD[iTamPacoteCMD-1];
if (byPacoteCRC == byPacoteCalcCRC )
{
iRetry = 0;
if (isdigit(ucPaco teCMD[1]))
{

ConfControl.con troladora = (BYTE)(
(ucPacoteCMD[1])- 48);
ConfControl.ten tativas = 5;
ConcedePrivileg io(hSerial,((BY TE)ucPacoteCMD
[1]-48));
PurgeComm(hSeri al, PURGE_RXCLEAR);
}
TraduzMens(ucPa coteCMD,iTamPac oteCMD);

/* teste do comando pede abastecimento
if (gets(cmd) != NULL)
{
y = dividePorCaract ere(cmd," ",lista);

if (y > 1)
{
if (strcmp(lista[0],"abast") == 0)
{
PedeAbastecimen toManual(atoi(l ista[1])
+100);
}
}
if (strcmp(cmd,"qu it") == 0)
{
break;
}
}
*/
}
break;
}
}
}

}

}
DesativaEquipam ento(true);
}

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Exec Code */

/*************** *************** *************** *************** ***********
main.cpp - The main() routine for all the "Basic Winsock" suite of
programs from the Winsock Programmer's FAQ. This function parses
the command line, starts up Winsock, and calls an external function
called DoWinsock to do the actual work.

This program is hereby released into the public domain. There is
ABSOLUTELY NO WARRANTY WHATSOEVER for this product. Caveat hacker.
*************** *************** *************** *************** ***********/

#include "IThreadConnect .hpp"
#include "IGerenciadorEq uipamento.hpp"
#include <windows.h>
#include <vector>
#include <algorithm>

using namespace std;

BOOL CtrlHandler(DWO RD fdwCtrlType)
{
switch( fdwCtrlType )
{
// Handle the CTRL+C signal.
case CTRL_C_EVENT:
//printf( "Ctrl-C event\n\n" );
Beep( 750, 300 );
return( TRUE );

// CTRL+CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVEN T:
Beep( 600, 200 );
//printf( "Ctrl-Close event\n\n" );
return( TRUE );

// Pass other signals to the next handler.
case CTRL_BREAK_EVEN T:
Beep( 900, 200 );
//printf( "Ctrl-Break event\n\n" );
return FALSE;

case CTRL_LOGOFF_EVE NT:
Beep( 1000, 200 );
//printf( "Ctrl-Logoff event\n\n" );
return FALSE;

case CTRL_SHUTDOWN_E VENT:
Beep( 750, 500 );
//printf( "Ctrl-Shutdown event\n\n" );
return FALSE;

default:
return FALSE;
}
system("PAUSE") ;
}

//// main //////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
IThreadConnect threadConnect(0 );
IGerenciadorEqu ipamento gerente1("COM1" , 9600, 8, SERIAL_PARITY_N ONE);
// IGerenciadorEqu ipamento gerente2("COM3" , 9600, 8, SERIAL_PARITY_N ONE);
// IGerenciadorEqu ipamento gerente3("COM3" , 9600, 8, SERIAL_PARITY_N ONE);

vector<IGerenci adorEquipamento > vEquipamento;

if( SetConsoleCtrlH andler((PHANDLE R_ROUTINE) CtrlHandler, TRUE))
{

gerente1.AtivaE quipamento();
printf("1 - Connected ! \n");

}
else
printf( "\nERROR: Could not set control handler");
//system("PAUSE") ;
// exit(1);
}

/*--------------------------------------------------------------------*/
/* until here */
Best Regards,
Leandro

--
Message posted via http://www.dotnetmonster.com
Nov 17 '05 #1
6 2872
"Leandro Berti via DotNetMonster.c om" <fo***@nospam.D otNetMonster.co m> wrote in message news:<01******* *************** ********@DotNet Monster.com>...
Hi All,

I wrote a code to do serial communication with an equipament.
When i use the code outside of threaded class it seens work properly,
but when i put inside a class and execute a thread in the first seconds the
communication is ok, later i receive read/write error.
I?ve been in MSDN site and there i discover that the read/write error is a
INVALID_HANDLE problem. But why??? I just create the serial communication
file and use it.
Anyone can help me?

Here is the code
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class */

#ifndef _IGERENCIADOREQ UIPAMENTO_H
#define _IGERENCIADOREQ UIPAMENTO_H

#include <stdio.h>
#include <windows.h>

#define SERIAL_PARITY_N ONE 0
#define SERIAL_PARITY_O DD 1
#define SERIAL_PARITY_E VEN 2

#define SERIAL_MAX_RX 256 // Input buffer max size
#define SERIAL_MAX_TX 256 // output buffer max size
#define SERIAL_CONNECTE D 0
#define SERIAL_DISCONNE CTED 1
#define SERIAL_DATA_SEN T 2
#define SERIAL_DATA_ARR IVAL 3
#define SERIAL_RING 4
#define SERIAL_CD_ON 5
#define SERIAL_CD_OFF 6
#define SERIAL_DATA_REC V 7

#define SERIAL_SIGNAL_N BR 7

class IGerenciadorEqu ipamento;

typedef struct
{
HANDLE serialFD;
IGerenciadorEqu ipamento* pIGE;
}_SERIALCOM_ION ICS;
class IGerenciadorEqu ipamento: public IThread
{

private:
HANDLE hSerial;
char *cPortaSerial;
DWORD dwBaudRate;
BYTE byByteSize;
BYTE byTipoParidade;
bool conectado;
bool bRX_In_Progress ; // BOOL indicating if a
ReadFile is
// in progress
bool bTX_In_Progress ; // BOOL indicating if a
WriteFile is
// in progress

unsigned char pacoteIN[256];
unsigned char pacoteOUT[256];

bool bConectado;

int ConfigTimeouts( COMMTIMEOUTS mCommtimeout);
int ConfigDCB(DCB mDCB);

public:
IGerenciadorEqu ipamento(char *mcPortaSerial, DWORD mdwBaudRate,
BYTE mbyByteSize, BYTE mbyiTipoParidad e);
~IGerenciadorEq uipamento();

int AtivaEquipament o(BOOL mbIniciaThread = true);
int DesativaEquipam ento(BOOL mbFinalizaThrea d = true);
int EscreveMensagem (HANDLE hSerialCOM,unsi gned char* mcMensagem, int
miTamanho);
int LeMensagem(HAND LE hSerialCOM,unsi gned char* mcMensagem, int
miTamanho);
void PurgeSerial(voi d);
bool VerificaEstado( void);
int Run(void);
HANDLE GetSerialHND(vo id);
void OnSendRecv(void );
unsigned char *GetDadosRecebi dos(void);
unsigned char *GetDadosEnviad os(void);

int EnviaPOLLING(HA NDLE hSerialCOM);
int ConcedePrivileg io(HANDLE hSerialCOM, BYTE byEndereco);
void TraduzMens(unsi gned char *ucPacote, DWORD miTamanho);
DWORD IGerenciadorEqu ipamento::Extra iCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT);
};

//DWORD WINAPI ComSendRecv(LPV OID p);
int ComSendRecv(LPV OID p);

#endif

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class Code */

//#define STRICT
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>
#include <iostream>
#include <math.h>
#include "IGerenciadorEq uipamento.hpp"
#include "StringMethods. hpp"
#include "Consts.hpp "
#include "TipoProtocolo. hpp"

#define SIG_POWER_DOWN 0
#define SIG_READER 1
#define SIG_READ_DONE 2 // data received has been read
#define SIG_WRITER 3
#define SIG_DATA_TO_TX 4 // data waiting to be sent
#define SIG_MODEM_EVENT S 5
#define SIG_MODEM_CHECK ED 6


using namespace std;
typedef struct
{
BYTE controladora;
BYTE tentativas;
bool detectaprot;
}STRU_CONFCONTR OL;
STRU_CONFCONTRO L ConfControl;

unsigned char *IGerenciadorEq uipamento::GetD adosRecebidos(v oid)
{
return pacoteOUT;
}

unsigned char *IGerenciadorEq uipamento::GetD adosEnviados(vo id)
{
return pacoteIN;
}

int IGerenciadorEqu ipamento::Envia POLLING(HANDLE hSerialCOM)
{
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
int iTotalLido;

ZeroMemory(ucPa coteIN,3);

ucPacoteIN[0] = SYN;
ucPacoteIN[1] = '1';
ucPacoteIN[2] = 0x55;

EscreveMensagem (hSerialCOM ,ucPacoteIN,3);
iTotalLido=LeMe nsagem(hSerialC OM ,ucPacoteOUT,30 );
if (iTotalLido)
{
if ((ucPacoteOUT[0] == SYN) && (ucPacoteOUT[1] == '1') &&
(ucPacoteOUT[2] == 0xAA))
ConfControl.det ectaprot = false;
}
return iTotalLido;
}

int IGerenciadorEqu ipamento::Conce dePrivilegio(HA NDLE hSerialCOM, BYTE
byEndereco)
{
unsigned char ucPacoteIN[256];
int iTotalEscrito;

ZeroMemory(ucPa coteIN,3);

// privilegio
ucPacoteIN[0] = SYN;
ucPacoteIN[1] = byEndereco+48;
ucPacoteIN[2] = ACK;

iTotalEscrito=E screveMensagem( hSerialCOM ,ucPacoteIN,3);
return iTotalEscrito;
}

void IGerenciadorEqu ipamento::Tradu zMens(unsigned char *ucPacote, DWORD
miTamanho)
{
int iCanal;
double dLitros;
char cPulsos[8];
double dPulsos;
char parcelaPacote;
char cInd;
int iInd;
int k;

dLitros = 0;
iCanal = ((((BYTE)ucPaco te[1])-49)*8);
iInd = ucPacote[3] & 0x0F;

switch(iInd)
{
case 0:
iCanal += ((((BYTE)ucPaco te[4])-47)+100);
printf("Bomba %i ligada\n",iCana l-100);
break;
case 1:
iCanal += ((((BYTE)ucPaco te[4])-47)+100);
printf("Bomba %i desligada\n",iC anal-100);

dPulsos = 0;
k=0;
ZeroMemory(cPul sos,8);
for (int i=5;i<13;i++)
{
cPulsos[k] = ucPacote[i];
k++;
}
dPulsos = atof(cPulsos);

dLitros = round(dPulsos/1*100)/100;

if ((iCanal > 100) && (iCanal < 133))
{
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, dLitros);
}
else
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, 0.00);

break;
case 7:
printf("APM Reenergizado\n" );
break;
}
}

DWORD IGerenciadorEqu ipamento::Extra iCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT)
{
int i;
DWORD dPosETX = 0;
DWORD dPosSTX = 0;
DWORD dPosDC2 = 0;
bool bOneMoreSYN;
bool bMensTexto;
bool bContinuar = true;
DWORD dBytesToSYN;
int iTotalBytes;

iTotalBytes = 0;
dBytesToSYN = 0;
bMensTexto = false;
bOneMoreSYN = true;
dPosETX = 0;
dPosSTX = 0;
dPosDC2 = 0;

for(i=dQtdebyte s-1;(i>=0);i--)
{

if (bOneMoreSYN)
dBytesToSYN++;

switch(ucPacote IN[i])
{
case SYN:
if ((dPosETX) && (dPosSTX) && ((dPosSTX-i) == 2) && (dQtdebytes
dPosETX))

{
bMensTexto = true;
bContinuar = false;
break;
}
else
{
if ((dPosDC2) && (dPosDC2-i) == 2)
{
if ((!bOneMoreSYN) && (dBytesToSYN > 0))
{
return iTotalBytes;
}
else
{
bContinuar = false;
break;
}
}
else
{
if (!bOneMoreSYN) { return 0; }
bOneMoreSYN = false;
dPosDC2 = 0;
dPosETX = 0;
dPosSTX = 0;
}

}
break;

case DC2: dPosDC2 = i; break;
case STX: dPosSTX = i; break;
case ETX: dPosETX = i; break;
}
if (!bContinuar) break;
}

if ((i != 0xFFFF) && (ucPacoteIN[i] == SYN))
{
if (bMensTexto)
dPosETX++;
else
dPosETX = dPosDC2;

for(int j=i;j<=dPosETX; j++)
{
ucPacoteOUT[iTotalBytes] = ucPacoteIN[j];
iTotalBytes++;
}
}
return iTotalBytes;
}
IGerenciadorEqu ipamento::IGere nciadorEquipame nto(char *mcPortaSerial,
DWORD mdwBaudRate,
BYTE mbyByteSize,
BYTE mbyTipoParidade )
{
cPortaSerial = mcPortaSerial;
dwBaudRate = mdwBaudRate;
mbyTipoParidade = mbyTipoParidade ;
mbyByteSize = mbyByteSize;
hSerial = INVALID_HANDLE_ VALUE;
conectado = false;
bRX_In_Progress = false;
bTX_In_Progress = false;
ConfControl.det ectaprot = true;
ConfControl.ten tativas = 0;
ConfControl.con troladora = 0;

}

IGerenciadorEqu ipamento::~IGer enciadorEquipam ento()
{
conectado = false;
cPortaSerial = "";
dwBaudRate = 0;
byTipoParidade = SERIAL_PARITY_N ONE;
byByteSize = 0;

if (GetThreadHND() !=0)
WaitForSingleOb ject(GetThreadH ND(), 2000);

bRX_In_Progress = false;
bTX_In_Progress = false;
if (hSerial != INVALID_HANDLE_ VALUE)
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;
}

int IGerenciadorEqu ipamento::Confi gTimeouts(COMMT IMEOUTS mCommtimeout)
{

// configura os timeouts da Porta Serial
mCommtimeout.Re adIntervalTimeo ut = 20;
mCommtimeout.Re adTotalTimeoutM ultiplier = 1;
mCommtimeout.Re adTotalTimeoutC onstant = 20;
mCommtimeout.Wr iteTotalTimeout Multiplier = 5;
mCommtimeout.Wr iteTotalTimeout Constant = 5;

return SetCommTimeouts (hSerial,&mComm timeout);
}

int IGerenciadorEqu ipamento::Confi gDCB(DCB mDCB)
{
// recupera as informa??es do DCB
if (!GetCommState( hSerial,&mDCB))
{
CloseHandle(hSe rial);
return ERROR_INVALID_H ANDLE;
}
// set DCB to configure the serial port
mDCB.DCBlength = sizeof(mDCB);

/* ---------- Serial Port Config ------- */
mDCB.BaudRate = dwBaudRate;

switch(byTipoPa ridade)
{
case SERIAL_PARITY_N ONE:
mDCB.Parity = NOPARITY;
mDCB.fParity = 0;
break;
case SERIAL_PARITY_E VEN:
mDCB.Parity = EVENPARITY;
mDCB.fParity = 1;
break;
case SERIAL_PARITY_O DD:
mDCB.Parity = ODDPARITY;
mDCB.fParity = 1;
break;
}
mDCB.StopBits = ONESTOPBIT;
mDCB.ByteSize = 8;
mDCB.fBinary = 0;
mDCB.fAbortOnEr ror = 0;
mDCB.wReserved = 0;
mDCB.XonLim = 100;
mDCB.XoffLim = 100;
mDCB.XonChar = 0x0D;
mDCB.XoffChar = 0x0A;
mDCB.ErrorChar = 0;
mDCB.EofChar = 0;
mDCB.EvtChar = 0;
mDCB.wReserved1 = 0;

return SetCommState(hS erial,&mDCB);

}
int IGerenciadorEqu ipamento::Ativa Equipamento(BOO L mbIniciaThread)
{
int iErro;
DCB dcb;
int i;

COMMTIMEOUTS cto;
if (hSerial != INVALID_HANDLE_ VALUE)
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;

if (cPortaSerial != "")
{
iErro = 0;

hSerial = CreateFile(cPor taSerial, // filename
GENERIC_READ | GENERIC_WRITE, // acesso
desejado
0, // modo de
compartilhament o
NULL, // atributos
de seguran?a
OPEN_EXISTING, // disposi??o
da cria??o do arquivo
FILE_FLAG_NO_BU FFERING,
// flag de cria??o
NULL); // indica se
pode ou n?o copiar os
// atributos do
arquivo atual para outro
// arquivo
if (hSerial != INVALID_HANDLE_ VALUE)
{
bConectado = true;

// aplica os timeous
if (!ConfigTimeout s(cto))
iErro = 2;

// aplica o DCB
if (!ConfigDCB(dcb ))
iErro = 4;

}
}
else
iErro = -2;
/* --------------------------------------------- */
if (iErro > 0)
{
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;
}
else
{

HANDLE hThread1;
DWORD dThreadID1;
if(mbIniciaThre ad)
{
printf("Connect ed ! \n");

hThread1 = CreateThread(NU LL, // default
security attributes
0, // use default
stack size
(DWORD (_stdcall *)(void *))ComSendRecv,
// thread function
(void*)this, // argument to thread
function
0, // use default
creation flags
&dThreadID1) ; // returns the
thread identifier

*/

}
}

/* --------------------------------------------- */
return iErro;

}
int IGerenciadorEqu ipamento::Desat ivaEquipamento( BOOL mbFinalizaThrea d)
{
conectado = false;

if(mbFinalizaTh read)
{

}
if (hSerial != INVALID_HANDLE_ VALUE)
CloseHandle(hSe rial);
hSerial = INVALID_HANDLE_ VALUE;
if (this->GetThreadHND() )
{
if (WaitForSingleO bject (this->GetThreadHND() , 2000) == WAIT_TIMEOUT)
{
TerminateThread (this->GetThreadHND() , 1);
CloseHandle (this->GetThreadHND() );
}
else CloseHandle (this->GetThreadHND() );
}
CloseHandle(thi s->GetThreadHND() );

printf("Disconn ected ! \n");

}

int IGerenciadorEqu ipamento::Escre veMensagem(HAND LE hSerialCOM,unsi gned
char* mcMensagem, int miTamanho)

{
char cTXBuffer[SERIAL_MAX_RX];
DWORD iQtdebytesEscri tos;
int iTamanhoBuffer = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;


if (!bTX_In_Progre ss)
{
PurgeComm(hSeri alCOM,PURGE_TXC LEAR | PURGE_RXCLEAR);
//hCom = hSerialCOM;

iSuccess = WriteFile(hSeri alCOM,
mcMensagem,
miTamanho,
&iQtdebytesEscr itos,
NULL);

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDIN G )
printf("erro: %i , qtde: %i => WriteFile error (not pending)\
n", Error,iQtdebyte sEscritos & 0xFFFF);
}

bTX_In_Progress = false;

}

return iQtdebytesEscri tos;
}
int IGerenciadorEqu ipamento::LeMen sagem(HANDLE hSerialCOM,unsi gned char*
mcMensagem, int miTamanho)
{
DWORD iQtdebytesLidos ;
DWORD iLenMensagem = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;

ZeroMemory(mcMe nsagem,SERIAL_M AX_RX);

if (!bRX_In_Progre ss)
{
// locking reading
bRX_In_Progress = true;
//hCom = hSerialCOM;

// starting a new read
iSuccess = ReadFile(hSeria lCOM, // handle do arquivo
mcMensagem, // buffer de leitura
miTamanho, // n?mero de bytes a serem lidos
&iQtdebytesLido s, // n?mero de bytes realmente
lidos
NULL); // usado para leitura
concorrente
// da serial

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDIN G)
{
printf("erro: %i , qtde: %i => Readfile error (not pending)\
n", Error,iQtdebyte sLidos & 0xFFFF);
}
}
bRX_In_Progress = false;
}

return iQtdebytesLidos ;
}

void IGerenciadorEqu ipamento::Purge Serial(void)
{
PurgeComm(hSeri al,PURGE_TXCLEA R | PURGE_RXCLEAR);
}

bool IGerenciadorEqu ipamento::Verif icaEstado(void)
{
// return (bRX_In_Progres s || bTX_In_Progress );
}

int ComSendRecv(LPV OID p)
{
IGerenciadorEqu ipamento* pIGE;

pIGE = (IGerenciadorEq uipamento*)p;

if (pIGE !=0)
return pIGE->Run();

}

BYTE CalculaCRC(unsi gned char *msg, int qtdeBytes)
{
BYTE valor_crc = 0;

for (int i=0; i<=qtdeBytes-1;i++)
{
valor_crc += msg[i];
}
return valor_crc;
}

int IGerenciadorEqu ipamento::Run(v oid)
{
bool bDone;
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
unsigned char ucPacoteCMD[256];
int iRetry;
BYTE byPacoteCRC, byPacoteCalcCRC ;
// char *lista[3];

int iTotalLido = 0;
int iTamPacoteCMD = 0;

bDone = false;
bRX_In_Progress = false;
bTX_In_Progress = false;

GetLastError(); // just to clear any pending error

HANDLE hComm = hSerial;

char cmd[5];

while(!bDone)
{

Sleep(1000);

if (ConfControl.de tectaprot)
EnviaPOLLING(hS erial);

if (ConfControl.co ntroladora)
{
iTotalLido = LeMensagem(hSer ial ,pacoteOUT,30);
if (iTotalLido)
{
ConcedePrivileg io(hSerial,Conf Control.control adora);
ConfControl.ten tativas = 5;
}
ConfControl.ten tativas--;
if (ConfControl.te ntativas <= 0)
{
ConfControl.ten tativas = 0;
ConfControl.con troladora = 0;
}
}

ConcedePrivileg io(hSerial,0);

iRetry = 1;

while (iRetry >0)
{

iRetry--;

iTotalLido = LeMensagem(hSer ial,ucPacoteOUT ,30);
if (iTotalLido)
{
ZeroMemory(ucPa coteCMD,SERIAL_ MAX_RX);

iTamPacoteCMD = ExtraiCMD
(ucPacoteOUT,1, iTotalLido,ucPa coteCMD);
if (iTamPacoteCMD > 0)
{

ZeroMemory(ucPa coteIN,SERIAL_M AX_RX);

switch(ucPacote CMD[2])
{
case DC2:
if (isdigit(ucPaco teCMD[1]))
{
iRetry = 1;
ConcedePrivileg io(hSerial,((BY TE)ucPacoteCMD[1]
-48));
}
break;

case STX:
byPacoteCalcCRC = CalculaCRC
(ucPacoteCMD,iT amPacoteCMD-1);
byPacoteCRC = (BYTE)ucPacoteC MD[iTamPacoteCMD-1];
if (byPacoteCRC == byPacoteCalcCRC )
{
iRetry = 0;
if (isdigit(ucPaco teCMD[1]))
{

ConfControl.con troladora = (BYTE)(
(ucPacoteCMD[1])- 48);
ConfControl.ten tativas = 5;
ConcedePrivileg io(hSerial,((BY TE)ucPacoteCMD
[1]-48));
PurgeComm(hSeri al, PURGE_RXCLEAR);
}
TraduzMens(ucPa coteCMD,iTamPac oteCMD);

/* teste do comando pede abastecimento
if (gets(cmd) != NULL)
{
y = dividePorCaract ere(cmd," ",lista);

if (y > 1)
{
if (strcmp(lista[0],"abast") == 0)
{
PedeAbastecimen toManual(atoi(l ista[1])
+100);
}
}
if (strcmp(cmd,"qu it") == 0)
{
break;
}
}
*/
}
break;
}
}
}

}

}
DesativaEquipam ento(true);
}

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Exec Code */

/*************** *************** *************** *************** ***********
main.cpp - The main() routine for all the "Basic Winsock" suite of
programs from the Winsock Programmer's FAQ. This function parses
the command line, starts up Winsock, and calls an external function
called DoWinsock to do the actual work.

This program is hereby released into the public domain. There is
ABSOLUTELY NO WARRANTY WHATSOEVER for this product. Caveat hacker.
*************** *************** *************** *************** ***********/

#include "IThreadConnect .hpp"
#include "IGerenciadorEq uipamento.hpp"
#include <windows.h>
#include <vector>
#include <algorithm>

using namespace std;

BOOL CtrlHandler(DWO RD fdwCtrlType)
{
switch( fdwCtrlType )
{
// Handle the CTRL+C signal.
case CTRL_C_EVENT:
//printf( "Ctrl-C event\n\n" );
Beep( 750, 300 );
return( TRUE );

// CTRL+CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVEN T:
Beep( 600, 200 );
//printf( "Ctrl-Close event\n\n" );
return( TRUE );

// Pass other signals to the next handler.
case CTRL_BREAK_EVEN T:
Beep( 900, 200 );
//printf( "Ctrl-Break event\n\n" );
return FALSE;

case CTRL_LOGOFF_EVE NT:
Beep( 1000, 200 );
//printf( "Ctrl-Logoff event\n\n" );
return FALSE;

case CTRL_SHUTDOWN_E VENT:
Beep( 750, 500 );
//printf( "Ctrl-Shutdown event\n\n" );
return FALSE;

default:
return FALSE;
}
system("PAUSE") ;
}

//// main //////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
IThreadConnect threadConnect(0 );
IGerenciadorEqu ipamento gerente1("COM1" , 9600, 8, SERIAL_PARITY_N ONE);
// IGerenciadorEqu ipamento gerente2("COM3" , 9600, 8, SERIAL_PARITY_N ONE);
// IGerenciadorEqu ipamento gerente3("COM3" , 9600, 8, SERIAL_PARITY_N ONE);

vector<IGerenci adorEquipamento > vEquipamento;

if( SetConsoleCtrlH andler((PHANDLE R_ROUTINE) CtrlHandler, TRUE))
{

gerente1.AtivaE quipamento();
printf("1 - Connected ! \n");

}
else
printf( "\nERROR: Could not set control handler");
//system("PAUSE") ;
// exit(1);
}

/*--------------------------------------------------------------------*/
/* until here */
Best Regards,
Leandro

Hi Leandro

It seems that your primary thread creates the new thread and then
return and exit the process, causing the ~IGerenciadorEq uipamento
destructor to run, hence closing the handle.

To find out if this is the problem, let the primary thread to Sleep()
after it creates the new thread.

Alon Fliess
Nov 17 '05 #2
Hi Alon,

Thanks for the help.
I try to put a Sleep() after the CreateThread() but doesn?t work and i mark
the breakpoint at the Destructor method and the execution don?t reach it.
The problem is at the beginning the communication work, then goes to
error state:
error: 6 => WriteFile error (not pending)
error: 6 => Readfile error (not pending)
Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com
Nov 17 '05 #3
Berti,

Can you tell if the handle value is the same right after you create it and
at the time when you get errors?

Your code looks ok (as long as you take into account Alon's suggestion).
One thing I'd suggest you change is replace CreateThread() with
_beginthread[ex](). You should not use the former in a multi-threaded
environment unless you are absolutely sure that your thread proc will not
call (implicitly or explicitly) runtime library functions that utilize
thread local storage.

I've written quite a bit of code that does rs232 to a lot of different
devices. Under Win32 I've done it with and without overlapped io and always
in a multi-threaded environment. This stuff seems to work fine. I don't
recall any gotchas. So, as in most of the cases, it's gotta be something in
your code :)

Bogdan
"Leandro Berti via DotNetMonster.c om" <fo***@DotNetMo nster.com> wrote in
message news:9f******** *************** *******@DotNetM onster.com...
Hi Alon,

Thanks for the help.
I try to put a Sleep() after the CreateThread() but doesn?t work and i
mark
the breakpoint at the Destructor method and the execution don?t reach it.
The problem is at the beginning the communication work, then goes to
error state:
error: 6 => WriteFile error (not pending)
error: 6 => Readfile error (not pending)
Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com

Nov 17 '05 #4
Hi Bogdan,

Answering your first question the Handle value is the same in all the cases.
I try your sugestion changed the CreateThread() to _beginthread[ex] and
doesn't work.
That is very weird because everything seems ok.
Can you tell me more about that shouldn?t use CreatThread in a Multi-thread
environment?
And maybe send me (le***********@ gmail.com) any code with multi-thread
architecture.

Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com
Nov 17 '05 #5
Berti,

It is very unlikely that CreateThread() vs _beginthread() issue is causing
your problems. Still, it is a good practice to use _beginthread() when you
use CRT. The compiler/linker will force you to use multi-threaded libraries
(one less thing to remember) and you'll make sure that all static buffers
are properly cleaned up when threads terminate. See "Multithreading "
(specifically "Multithrea ding with C and Win32") in MSDN.

Your problems might be caused by a lack of synchronization when it comes to
access to class members. You've got quite a bit of public methods (I'm not
sure if this is intentional) that could potentially lead to race conditions.
Some of the methods take a comm handle which is also confusing. Another
thing that you might try to avoid is to pass structures by value (e.g. DCB,
timeouts) - simply unnecessary burden on the stack.

I'd suggest that you start with refactoring the code so the serial comms
related stuff is not mixed with your application code. I'm pretty sure that
this would make it much easier for you and guys in this newsgroup to
troubleshoot problems.

Let's see if I can be of any help off-line. I'll send you an e-mail later
today.

Bogdan
"Leandro Berti via DotNetMonster.c om" <fo***@DotNetMo nster.com> wrote in
message news:e7******** *************** *******@DotNetM onster.com...
Hi Bogdan,

Answering your first question the Handle value is the same in all the
cases.
I try your sugestion changed the CreateThread() to _beginthread[ex] and
doesn't work.
That is very weird because everything seems ok.
Can you tell me more about that shouldn?t use CreatThread in a
Multi-thread
environment?
And maybe send me (le***********@ gmail.com) any code with multi-thread
architecture.

Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com

Nov 17 '05 #6
"Leandro Berti via DotNetMonster.c om" <fo***@DotNetMo nster.com> wrote in message news:<e7******* *************** ********@DotNet Monster.com>...
Hi Bogdan,

Answering your first question the Handle value is the same in all the cases.
I try your sugestion changed the CreateThread() to _beginthread[ex] and
doesn't work.
That is very weird because everything seems ok.
Can you tell me more about that shouldn?t use CreatThread in a Multi-thread
environment?
And maybe send me (le***********@ gmail.com) any code with multi-thread
architecture.

Best Regards,
Berti


CreateThread is a Win32 API that does not take into account the C++
runtime. When you call some of the C/C++ runtime functions, they may
need to refer to a buffer created and initiated by the runtime. The
main thread creates this buffer before it calls your main() function.
In MT program, each thread should use its own buffer, so there has to
be a way to create this buffer for each of them. Using the
_beginthread[ex]() function lets the runtime prepare this buffer. It
also add a default exception handler around your code (for un-handled
exceptions and ANSI-C signal handling, and handles the atexit()
function (hence it handles destructors of static objects in C++) ).
CreateThread still works because whenever you call a function that
needs the buffer it checks if the buffer does not exist, and if so it
creates one. however this buffer will stay in memory even if your
thread has exit and there will be no other c/c++ support (signal and
atexit()). If you use _beginthread, c/c++ runtime will free the
buffer. There is one case the C/C++ runtime can create/destroy the
buffer for you even if you use CreateThread, and it is when you use
the DLL version of the runtime. The runtime uses the
DLL_THREAD_ATTA CHED/DETACHED to handle initialization/finalization.
In any case you always have to use the MT runtime (even if you use
CreateThread) and this is one of the main reason to use the
_beginthread[ex] function, it forces you to compile in MT.

After all this explanation, I don't think that CreateThread is your
problem.
First, check if you compile with the MT version of the runtime.
Second, use Process Explorer from www.sysinternals.com. Check if the
handle is valid (you may also see when it becomes invalid - it will
become red and will disappear).

Alon Fliess
CTO
The Sela Group
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
4562
by: Mike C. | last post by:
I am trying to get Java v1.4.2 to use my PCI add-on serial port. So far, everything I try gives me javax.comm.NoSuchPortException at javax.comm.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:105) at org.sf.javaemu.Serial.SerialCommunications.openConnection(UnknownSource) at javaemu.main.init(Unknown Source)
0
1043
by: David | last post by:
I have been having a problem trying to transfer Serial Communications code over to .NET Web Services. Needs to stay in C++ and as a web service. The code will open the serial comm port and receive data, but when I try to close the port it will not close. I have to go into the task manager and kill the aspnet_wp.exe process before it will close. The same code will work in a generic C++ project. If anyone has had problems like this...
1
3633
by: Mike | last post by:
Sorry, don't know if this is the correct board for my question. I'm a novice so I guess I have a valid excuse My question : I'm using Visual C++ and I need to collect data from a serial port. Specifically, I have a piece of equipment that outputs ASCII data to my computer through the serial port. Is there some way I can call the serial port from within Vis C++ and then save the data I'd much rather do this than buy some sort of software,...
7
2765
by: Michael Chong | last post by:
I wrote a program that communicate with SerialComm. In every 300 milliseconds, my program continuously send & receive data via the serial port once the program starts. My program is once in a while, the serial port seems corrupted because when my data is sent, it doesn't go through the serial port, so as same to receive process. In order to fix this, I have to close the port and reopen the port again. Why?!! Is there any way to fix...
0
7917
by: coolsilver.net | last post by:
I am not sure if I am in the right group. My problem is this: My VB.NET application prints to the Epson printer using Epson OPOS drivers. I have downloaded the Epson ADK for .NET from the EpsonExpert site (www.epsonexpert.com) I have also downloaded the Epson Advanced Printer Driver from the Epson site. I have installed Microsot POS for .NET on a windows 2000 machine. The installation completes but it throws an error "Error 5008....
12
2126
by: ken | last post by:
Hello everyone, I'm new to visual VB and I am trying to setup communications to the outside world. I found the example listed below in the help section of Microsoft Visual Basic 2005 Express Edition. Using the Hyper Terminal should I be able to see the string "Hello" or am I completely off base here? Thank you in advance for all and any help. Best regards, Ken Sub SendSerialData(ByVal data As String) ' Send strings to a serial port.
3
3686
by: ... | last post by:
Hi I need to send a chr(255) to a serial port. When I send it, through comm.write (chr(255)) it sends a chr(63) ... in Hex, I write chr(&FF) and it actually sends chr(&3F) ... why does this happen, and how can I send it right ? I'm using vb.net 2005 express with framework 2.0 Thanks for an answear ...
0
1433
by: joaquimfpinto | last post by:
Hi All, I've an application that write and read from different serial ports. I made a class with an object from Charon Communications. On the main form I create several instances of that class, depending on the number of serial ports I want to handle, and control any input data with a timer that is checking the machine attached to the serial port and whenever there is information the data available is triggered.
3
2482
by: John Dann | last post by:
Trying to learn Python here, but getting tangled up with variable scope across functions, modules etc and associated problems. Can anyone advise please? Learning project is a GUI-based (wxPython) Python program that needs to access external data across a serial port. The first thing that I need the program to do when it starts up is to check that it can see the serial port, the first step of which is to check that it can import the...
0
8965
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9466
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9255
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9202
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6050
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4567
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4823
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3278
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2191
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.